Skip to content

Commit

Permalink
[Ops] Decouple serverless release from tags (#176505)
Browse files Browse the repository at this point in the history
## Summary
Removes resource def and pipeline for:
https://buildkite.com/elastic/kibana-serverless-release
Adds a step after deploy tag creation to trigger a GPCTL release flow
for the commit hash - this step needs to be emitted because some of its
parameters are not available at the time of uploading the original
pipeline file.

- [x] Test without firing off a release
<img width="1250" alt="Screenshot 2024-02-23 at 11 43 08"
src="https://github.com/elastic/kibana/assets/4738868/f8b2fd04-8b44-4beb-949e-5f45a3573bc5">

Closes elastic/kibana-operations#59 - see this
for the full context.

---------

Co-authored-by: Thomas Watson <w@tson.dk>
  • Loading branch information
delanni and watson authored Feb 23, 2024
1 parent 623177f commit 171b758
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 70 deletions.
21 changes: 20 additions & 1 deletion .buildkite/pipeline-utils/buildkite/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface BuildkiteGroup {
steps: BuildkiteStep[];
}

export type BuildkiteStep = BuildkiteCommandStep | BuildkiteInputStep;
export type BuildkiteStep = BuildkiteCommandStep | BuildkiteInputStep | BuildkiteTriggerStep;

export interface BuildkiteCommandStep {
command: string;
Expand Down Expand Up @@ -94,6 +94,25 @@ export interface BuildkiteInputStep {
env?: { [key: string]: string };
}

export interface BuildkiteTriggerStep {
trigger: string;
label?: string;
build?: {
message?: string; // The message for the build. Supports emoji.
commit?: string; // The commit hash for the build.
branch?: string; // The branch for the build.
meta_data?: string; // A map of meta-data for the build.
env?: Record<string, string>; // A map of environment variables for the build.
};
async?: boolean;
branches?: string;
if?: string;
allow_dependency_failure?: boolean;
soft_fail?: boolean;
depends_on?: string | string[];
skip?: string;
}

export interface BuildkiteTriggerBuildParams {
commit: string;
branch: string;
Expand Down
12 changes: 0 additions & 12 deletions .buildkite/pipelines/pipeline.kibana-serverless-release.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ steps:
- ts-node .buildkite/scripts/serverless/create_deploy_tag/release_wizard_messaging.ts --state create_deploy_tag
- bash .buildkite/scripts/serverless/create_deploy_tag/create_deploy_tag.sh
- ts-node .buildkite/scripts/serverless/create_deploy_tag/release_wizard_messaging.ts --state tag_created
- ts-node .buildkite/scripts/serverless/create_deploy_tag/generate_gpctl_trigger.ts
- ts-node .buildkite/scripts/serverless/create_deploy_tag/release_wizard_messaging.ts --state trigger_gpctl
env:
DRY_RUN: $DRY_RUN

- wait: ~
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ else
echo "Skipping tag push to GitHub due to DRY_RUN=$DRY_RUN"
fi

echo "Created deploy tag: $DEPLOY_TAG - your QA release should start @ https://buildkite.com/elastic/kibana-serverless-release/builds?branch=$DEPLOY_TAG"
echo "Created deploy tag: $DEPLOY_TAG"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { buildkite } from './shared';
import { getSelectedCommitHash } from './info_sections/commit_info';
import { BuildkiteTriggerStep } from '#pipeline-utils';

const IS_DRY_RUN = process.env.DRY_RUN?.match(/(1|true)/i);
const REMOTE_SERVICE_CONFIG = `https://raw.githubusercontent.com/elastic/serverless-gitops/main/gen/gpctl/kibana/config.yaml`;

async function main() {
const selectedSha = getSelectedCommitHash();
uploadTriggerStep(selectedSha);
}

function uploadTriggerStep(commitSha: string) {
const triggerStep: BuildkiteTriggerStep = {
label: ':releasethekaken: Trigger GPCTL / Release Kibana',
trigger: 'gpctl-promote',
async: true,
build: {
message: 'Triggered by Kibana serverless release pipeline',
env: {
SERVICE_COMMIT_HASH: commitSha.slice(0, 12),
REMOTE_SERVICE_CONFIG,
},
},
};

if (IS_DRY_RUN) {
console.log('Dry run: skipping upload of GPCTL trigger step. Step definition:', triggerStep);
} else {
buildkite.uploadSteps([triggerStep]);
}
}

main()
.then(() => {
console.log('GPCTL Trigger step uploaded.');
})
.catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ type StateNames =
| 'wait_for_confirmation'
| 'create_deploy_tag'
| 'tag_created'
| 'trigger_gpctl'
| 'end'
| 'error_generic'
| string;
| 'error_generic';

interface StateShape {
name: string;
Expand Down Expand Up @@ -117,7 +117,20 @@ const states: Record<StateNames, StateShape> = {
name: 'Release tag created',
description: 'The initial step release is completed, follow up jobs will be triggered soon.',
instruction: `<h3>Deploy tag successfully created!</h3>`,
post: async () => {
instructionStyle: 'success',
display: true,
},
trigger_gpctl: {
name: 'Triggering GPCTL deployment',
description: 'Triggering the GPCTL deployment for the release - sit back and relax.',
instruction: `GPCTL deployment triggered, follow the trigger step for more info.`,
instructionStyle: 'info',
display: true,
},
end: {
name: 'End of the release process',
description: 'The release process has ended.',
pre: async () => {
// The deployTag here is only for communication, if it's missing, it's not a big deal, but it's an error
const deployTag =
buildkite.getMetadata(DEPLOY_TAG_META_KEY) ||
Expand All @@ -128,8 +141,7 @@ const states: Record<StateNames, StateShape> = {
buildkite.setAnnotation(
WIZARD_CTX_INSTRUCTION,
'success',
`<h3>Deploy tag successfully created!</h3><br/>
Your deployment will appear <a href='https://buildkite.com/elastic/kibana-serverless-release/builds?branch=${deployTag}'>here on buildkite.</a>`
`<h3>Release successfully initiated!</h3>`
);

if (!selectedCommit) {
Expand All @@ -153,12 +165,6 @@ Your deployment will appear <a href='https://buildkite.com/elastic/kibana-server
deployTag,
});
},
instructionStyle: 'success',
display: true,
},
end: {
name: 'End of the release process',
description: 'The release process has ended.',
display: false,
},
error_generic: {
Expand All @@ -179,15 +185,15 @@ export async function main(args: string[]) {
if (!args.includes('--state')) {
throw new Error('Missing --state argument');
}
const targetState = args.slice(args.indexOf('--state') + 1)[0];
const targetState = args.slice(args.indexOf('--state') + 1)[0] as StateNames;

let data: any;
if (args.includes('--data')) {
data = args.slice(args.indexOf('--data') + 1)[0];
}

const resultingTargetState = await transition(targetState, data);
if (resultingTargetState === 'tag_created') {
if (resultingTargetState === 'trigger_gpctl') {
return await transition('end');
} else {
return resultingTargetState;
Expand All @@ -196,7 +202,7 @@ export async function main(args: string[]) {

export async function transition(targetStateName: StateNames, data?: any) {
// use the buildkite agent to find what state we are in:
const currentStateName = buildkite.getMetadata('release_state') || 'start';
const currentStateName = (buildkite.getMetadata('release_state') || 'start') as StateNames;
const stateData = JSON.parse(buildkite.getMetadata('state_data') || '{}');

if (!currentStateName) {
Expand Down Expand Up @@ -243,10 +249,10 @@ function updateWizardState(stateData: Record<string, 'ok' | 'nok' | 'pending' |
: `<h3>:kibana: Kibana Serverless deployment wizard :mage:</h3>`;

const wizardSteps = Object.keys(states)
.filter((stateName) => states[stateName].display)
.filter((stateName) => !(IS_AUTOMATED_RUN && states[stateName].skipWhenAutomated))
.filter((stateName) => states[stateName as StateNames].display)
.filter((stateName) => !(IS_AUTOMATED_RUN && states[stateName as StateNames].skipWhenAutomated))
.map((stateName) => {
const stateInfo = states[stateName];
const stateInfo = states[stateName as StateNames];
const stateStatus = stateData[stateName];
const stateEmoji = {
ok: ':white_check_mark:',
Expand All @@ -271,7 +277,7 @@ ${wizardSteps.join('\n')}
}

function updateWizardInstruction(targetState: string, stateData: any) {
const { instructionStyle, instruction } = states[targetState];
const { instructionStyle, instruction } = states[targetState as StateNames];

if (IS_AUTOMATED_RUN) {
buildkite.setAnnotation(
Expand Down
39 changes: 1 addition & 38 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,43 +119,6 @@ spec:
system: control-plane

---

apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: kibana-serverless-release
description: Definition of the kibana release pipeline
links:
- title: Pipeline
url: https://buildkite.com/elastic/kibana-serverless-release
spec:
type: buildkite-pipeline
owner: group:kibana-operations
system: buildkite
implementation:
apiVersion: buildkite.elastic.dev/v1
kind: Pipeline
metadata:
name: kibana-serverless-release
description: Pipeline that releases kibana by triggering the release flow through qa, staging, and production
spec:
repository: elastic/kibana
pipeline_file: ./.buildkite/pipelines/pipeline.kibana-serverless-release.yaml
provider_settings:
build_branches: false
build_pull_request_forks: false
build_tags: true
# https://regex101.com/r/tY52jo/1
filter_condition: 'build.tag =~ /^deploy@\d+$/'
filter_enabled: true
teams:
kibana-operations:
access_level: MANAGE_BUILD_AND_READ
kibana-tech-leads:
access_level: MANAGE_BUILD_AND_READ
everyone:
access_level: READ_ONLY
---
# yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json
apiVersion: backstage.io/v1alpha1
kind: Resource
Expand Down Expand Up @@ -246,4 +209,4 @@ spec:
kibana-release-operators:
access_level: BUILD_AND_READ
everyone:
access_level: READ_ONLY
access_level: READ_ONLY

0 comments on commit 171b758

Please sign in to comment.