From a5ca949ff9155708b9b2c78442b5b704aac74005 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Sep 2026 10:51:58 -0500 Subject: [PATCH 1/3] fix(ci): rewrite release pipeline to be default-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three changes: 1. Add explicit 'Build type' input that defaults to Snapshot. Release builds require the operator to actively choose 'Release' AND trigger from an N.N branch — releasing from main is rejected. 2. Fix the snapshot detection race from build #75. The old 'Determine if snapshot' step ran inside the build groups (parallel with the build), so is_snapshot could be read before it was set. Now resolved in a single sequential step before any build runs. 3. Add is_snapshot validation in publish-common.sh — fail loudly if the value is missing or garbled rather than silently publishing a release. Co-Authored-By: Claude Opus 4.6 (1M context) --- .buildkite/publish/publish-common.sh | 5 ++++ .buildkite/release-pipeline.yml | 45 ++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.buildkite/publish/publish-common.sh b/.buildkite/publish/publish-common.sh index 91b7909b..fa5bd131 100755 --- a/.buildkite/publish/publish-common.sh +++ b/.buildkite/publish/publish-common.sh @@ -18,6 +18,11 @@ VERSION=$(cat "$VERSION_PATH") IS_SNAPSHOT=$(buildkite-agent meta-data get is_snapshot) IS_LATEST=$(buildkite-agent meta-data get is_latest) +if [[ "${IS_SNAPSHOT}" != "true" && "${IS_SNAPSHOT}" != "false" ]]; then + echo "!! is_snapshot has unexpected value '${IS_SNAPSHOT}'. Aborting to prevent accidental release." + exit 2 +fi + if [[ "${IS_SNAPSHOT:-}" == "false" && "${IS_LATEST:-}" == "true" ]]; then # don't apply LATEST tag to SNAPSHOT builds export APPLY_LATEST_TAG="true" diff --git a/.buildkite/release-pipeline.yml b/.buildkite/release-pipeline.yml index 695171d7..905a6066 100644 --- a/.buildkite/release-pipeline.yml +++ b/.buildkite/release-pipeline.yml @@ -1,5 +1,8 @@ ## 🏠/.buildkite/pipeline-release.yml -# Manual triggered pipeline to build and publish Docker images +# Manual triggered pipeline to build and publish Docker images. +# +# Defaults to SNAPSHOT. To publish a release image, the operator must +# explicitly choose "Release" in the input step AND trigger from an N.N branch. notify: - if: 'build.branch =~ /^((main)|([0-9]+\.[0-9]+))\$/ && (build.state == "failed" || pipeline.started_passing)' @@ -11,8 +14,19 @@ notify: steps: - input: "Build information" fields: + - select: "Build type" + key: "build_type" + hint: "Snapshot is the default. Choose Release only when cutting an actual release from an N.N branch." + default: "snapshot" + options: + - label: "Snapshot" + value: "snapshot" + - label: "Release" + value: "release" - select: "Apply :latest tag?" key: "is_latest" + hint: "Only applies to Release builds. Ignored for Snapshots." + default: "false" options: - label: "Yes" value: "true" @@ -21,20 +35,32 @@ steps: - wait: ~ # ---- - # Set is_snapshot to false initially + # Resolve build type into is_snapshot metadata. + # Release builds are only allowed from N.N branches — requesting a + # release from main is rejected to prevent accidents. # ---- - - command: "buildkite-agent meta-data set is_snapshot false" + - label: ":shield: Resolve build type" + command: | + BUILD_TYPE=$$(buildkite-agent meta-data get build_type) + if [[ "$$BUILD_TYPE" == "release" ]]; then + if [[ "$$BUILDKITE_BRANCH" == "main" ]]; then + echo "ERROR: Release builds cannot be triggered from main. Use an N.N branch." + exit 1 + fi + buildkite-agent meta-data set is_snapshot false + echo "Build type: RELEASE (branch: $$BUILDKITE_BRANCH)" + else + buildkite-agent meta-data set is_snapshot true + echo "Build type: SNAPSHOT (branch: $$BUILDKITE_BRANCH)" + fi + - wait: ~ # ---- # Docker builds for amd64 # ---- - group: ":package: amd64 Build and Test" key: "build_and_test_amd64" - if: "(build.branch =~ /^[0-9]+\\.[0-9x]+.*/ || build.branch == \"main\")" steps: - - label: "Determine if snapshot" - command: "buildkite-agent meta-data set is_snapshot true" - if: "(build.branch == \"main\")" - label: "Building amd64 Docker image" agents: provider: aws @@ -64,11 +90,7 @@ steps: # ---- - group: ":package: arm64 Build and Test" key: "build_and_test_arm64" - if: "(build.branch =~ /^[0-9]+\\.[0-9x]+.*/ || build.branch == \"main\")" steps: - - label: "Determine if snapshot" - command: "buildkite-agent meta-data set is_snapshot true" - if: "(build.branch == \"main\")" - label: "Building arm64 Docker image" agents: provider: aws @@ -101,7 +123,6 @@ steps: # Multiarch Docker image build and push # ---- - group: ":truck: Publish images" - if: "(build.branch =~ /^[0-9]+\\.[0-9x]+.*/ || build.branch == \"main\")" depends_on: - "build_and_test_amd64" - "build_and_test_arm64" From c35c9eeab98a257f2f777f86268413f73398d3a3 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Sep 2026 10:54:24 -0500 Subject: [PATCH 2/3] chore: bump main to 1.1.0 and add RELEASING.md main's product_version was incorrectly set to 1.0.1, which conflicts with the 1.0 maintenance branch where patch releases belong. Bump to 1.1.0. Add RELEASING.md documenting the release process, branch model, and post-release steps. Co-Authored-By: Claude Opus 4.6 (1M context) --- RELEASING.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ product_version | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 RELEASING.md diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..62c1ab61 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,63 @@ +# Releasing + +## Version scheme + +`MAJOR.MINOR.PATCH` stored in the `product_version` file. Independent of the Elastic stack release schedule. + +**Branch model:** +- `main` — next minor/major development line (e.g. `1.1.0`). Builds always produce `-SNAPSHOT` images. +- `N.N` branch (e.g. `1.0`) — maintenance branch for that minor line. Patch releases (`1.0.1`, `1.0.2`, …) are cut from here. + +## Cutting a release + +### 1. Docker image (via Buildkite) + +Trigger the **crawler-docker-build-publish** pipeline manually: + +1. Select the `N.N` branch (e.g. `1.0`) — **not** `main`. +2. Set **Build type** to **Release**. (Default is Snapshot — the pipeline will reject Release builds from `main`.) +3. Set **Apply :latest tag** to **Yes** only for the newest GA release. +4. The pipeline reads `product_version` from the branch to determine the image tag. + +### 2. GitHub release tag + +1. Create a GitHub release at `elastic/crawler/releases`. +2. Tag: `v{major}.{minor}.{patch}` (e.g. `v1.0.1`). +3. Target: the **same commit SHA** as the Buildkite build. +4. GitHub will auto-generate release notes. + +Both artifacts must target the same commit. + +## After a release + +### After a patch release (e.g. released `1.0.1` from `1.0`) + +Bump `product_version` on the `N.N` branch to the next patch: +```bash +# On a PR targeting the 1.0 branch: +echo "1.0.2" > product_version +``` +No change needed on `main`. + +### After a minor release (e.g. released `1.1.0`) + +1. Cut the `N.N` branch from the release commit: + ```bash + git checkout -b 1.1 v1.1.0 + git push origin 1.1 + ``` +2. Bump `product_version` on `main` to the next minor: + ```bash + # On a PR targeting main: + echo "1.2.0" > product_version + ``` +3. Add `"1.1"` to `targetBranchChoices` in `.backportrc.json`. + +## Snapshot builds + +Triggering the pipeline with the default "Snapshot" build type produces a +`-SNAPSHOT` image. This is safe to do from any branch at any time. + +## Internal runbook + +Full step-by-step: `search-team/teams/agent-builder/agent-builder-1/crawler/releasing-new-crawler-versions` in the internal team docs. diff --git a/product_version b/product_version index 7dea76ed..9084fa2f 100644 --- a/product_version +++ b/product_version @@ -1 +1 @@ -1.0.1 +1.1.0 From 6e0f01fac381f8e703634711f55f5dfac9d28459 Mon Sep 17 00:00:00 2001 From: Erik Currin Date: Fri, 18 Sep 2026 12:44:48 -0400 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .buildkite/release-pipeline.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.buildkite/release-pipeline.yml b/.buildkite/release-pipeline.yml index 905a6066..38db4c27 100644 --- a/.buildkite/release-pipeline.yml +++ b/.buildkite/release-pipeline.yml @@ -42,9 +42,8 @@ steps: - label: ":shield: Resolve build type" command: | BUILD_TYPE=$$(buildkite-agent meta-data get build_type) - if [[ "$$BUILD_TYPE" == "release" ]]; then - if [[ "$$BUILDKITE_BRANCH" == "main" ]]; then - echo "ERROR: Release builds cannot be triggered from main. Use an N.N branch." + if [[ ! "$$BUILDKITE_BRANCH" =~ ^[0-9]+\.[0-9]+$$ ]]; then + echo "ERROR: Release builds require an N.N branch (for example, 1.0)." exit 1 fi buildkite-agent meta-data set is_snapshot false