From 71607ea9f976286d5fbe974d7fd8d6f848ebff0e Mon Sep 17 00:00:00 2001 From: Dylan Dreyer Date: Mon, 17 Aug 2026 17:49:02 -0700 Subject: [PATCH 1/2] feat(ci): adopt ST release versioning and git tagging Aligns the distroless build with startree-dex's st-release.yml scheme: an upstream base version plus a StarTree build number. base_version 0.49.0 + build_number 1 -> v0.49.0-ST-1 Input changes: - version + tag_suffix -> base_version (default 0.49.0) + build_number - new tag_latest toggle (default true) to also push :latest The build still uses the plain upstream version to name the tarball, because the Makefile writes vector-${VERSION}-.tar.gz and the distroless Dockerfile globs `vector-0*`. The ST suffix belongs to the image tag only. A warning is emitted if base_version disagrees with Cargo.toml on the built ref. Adds a `release` job that creates and pushes an annotated git tag, and writes a step summary of what shipped. Unlike the dex workflow it tags *after* a successful publish rather than before the build, so a failed build cannot leave an orphan release tag. To catch the common mistake early, `metadata` fails in seconds if the release tag already exists rather than after a 90-minute build. Needs contents: write for the tag push. Co-Authored-By: Claude Opus 5 (1M context) --- .../workflows/startree-distroless-build.yml | 113 +++++++++++++++--- 1 file changed, 99 insertions(+), 14 deletions(-) diff --git a/.github/workflows/startree-distroless-build.yml b/.github/workflows/startree-distroless-build.yml index f25a3f974b3c6..744c8ab5c3d74 100644 --- a/.github/workflows/startree-distroless-build.yml +++ b/.github/workflows/startree-distroless-build.yml @@ -6,6 +6,14 @@ # Replaces sections 2.1-2.5 of: # https://startree.atlassian.net/wiki/spaces/CORTEXDATA/pages/1987543044/Re-sync+Vector.dev+on+the+startree+fork # +# Release versioning follows the same scheme as startree-dex's st-release.yml: +# an upstream base version plus a StarTree build number. +# +# base_version 0.49.0 + build_number 1 -> v0.49.0-ST-1 +# +# Each release pushes that image tag (optionally :latest too) and creates a +# matching annotated git tag on the built commit. +# # Required repository secrets: # STARTREE_REGISTRY_USERNAME - repo.startreedata.io login # STARTREE_REGISTRY_PASSWORD - repo.startreedata.io token/password @@ -24,21 +32,26 @@ on: # st-master is the StarTree integration branch: upstream + our patches. # `master` is a pristine upstream mirror and will not build our features. default: st-master - version: - description: "Version for the image tag (blank = read from Cargo.toml)" - required: false - default: "" - tag_suffix: - description: "Tag suffix. 'multiarch' -> v0.49.0-multiarch" - required: false - default: multiarch + base_version: + description: "Upstream Vector version this release is based on, e.g. 0.49.0" + required: true + default: "0.49.0" + build_number: + description: "StarTree build number. 0.49.0 + 1 -> v0.49.0-ST-1" + required: true + default: "1" + tag_latest: + description: "Also push the :latest tag" + type: boolean + default: true push: description: "Push to the registry (uncheck for a build-only dry run)" type: boolean default: true +# contents: write is needed to push the release git tag. permissions: - contents: read + contents: write concurrency: group: startree-distroless-${{ inputs.git_ref }} @@ -59,24 +72,55 @@ jobs: outputs: version: ${{ steps.resolve.outputs.version }} tag: ${{ steps.resolve.outputs.tag }} + image_tags: ${{ steps.resolve.outputs.image_tags }} steps: - uses: actions/checkout@v4 with: repository: startreedata/vector ref: ${{ inputs.git_ref }} + # Needed so the tag-existence check below sees existing tags. + fetch-depth: 0 - id: resolve run: | set -euo pipefail - VERSION="${{ inputs.version }}" - if [ -z "$VERSION" ]; then - VERSION="$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)" + VERSION="${{ inputs.base_version }}" + BUILD="${{ inputs.build_number }}" + TAG="v${VERSION}-ST-${BUILD}" + + # The Makefile names the tarball vector-${VERSION}-.tar.gz and the + # distroless Dockerfile globs `vector-0*`. Keep VERSION as the plain + # upstream version -- the ST suffix belongs to the image tag only. + CARGO_VERSION="$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)" + if [ "$VERSION" != "$CARGO_VERSION" ]; then + echo "::warning::base_version ($VERSION) does not match Cargo.toml ($CARGO_VERSION) on ${{ inputs.git_ref }}" fi - TAG="v${VERSION}-${{ inputs.tag_suffix }}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "tag=$TAG" >> "$GITHUB_OUTPUT" + + { + echo "image_tags<> "$GITHUB_OUTPUT" + echo "Building $VERSION -> ${IMAGE}:${TAG}" + # Fail in seconds rather than after a 90-minute build if this release + # number was already cut. + - name: Check the release tag is free + if: inputs.push + run: | + set -euo pipefail + TAG="${{ steps.resolve.outputs.tag }}" + if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then + echo "::error::git tag ${TAG} already exists; bump build_number" + exit 1 + fi + echo "${TAG} is free" + build: name: Build ${{ matrix.triple }} needs: metadata @@ -195,7 +239,7 @@ jobs: file: ${{ env.DOCKERFILE }} platforms: linux/amd64,linux/arm64 push: ${{ inputs.push }} - tags: ${{ env.IMAGE }}:${{ needs.metadata.outputs.tag }} + tags: ${{ needs.metadata.outputs.image_tags }} # Buildx emits attestation manifests by default, which surface as # "unknown/unknown" entries in `imagetools inspect`. Off, so the manifest # matches the shape the current imagetools-stitched tag has. @@ -205,3 +249,44 @@ jobs: if: inputs.push run: | docker buildx imagetools inspect "${IMAGE}:${{ needs.metadata.outputs.tag }}" + + release: + name: Tag the release + needs: [metadata, build, publish] + if: inputs.push + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + repository: startreedata/vector + ref: ${{ inputs.git_ref }} + + # Tagged only after publish succeeds, so a failed build never leaves an + # orphan release tag behind. + - name: Create and push the release tag + run: | + set -euo pipefail + TAG="${{ needs.metadata.outputs.tag }}" + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git tag -a "$TAG" -m "StarTree release $TAG (upstream ${{ inputs.base_version }}, build ${{ inputs.build_number }})" + git push origin "$TAG" + echo "Tagged $(git rev-parse --short HEAD) as $TAG" + + - name: Summary + run: | + { + echo "### StarTree Vector release \`${{ needs.metadata.outputs.tag }}\`" + echo + echo "| | |" + echo "|---|---|" + echo "| Built from | \`${{ inputs.git_ref }}\` |" + echo "| Upstream base | \`${{ inputs.base_version }}\` |" + echo "| StarTree build | \`${{ inputs.build_number }}\` |" + echo + echo "Images pushed:" + echo '```' + echo "${{ needs.metadata.outputs.image_tags }}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" From 5cc15eded08e21f2da26820480bca980d71537e2 Mon Sep 17 00:00:00 2001 From: Dylan Dreyer Date: Mon, 17 Aug 2026 17:52:45 -0700 Subject: [PATCH 2/2] refactor(ci): drop git_ref and tag_latest inputs git_ref duplicated what workflow_dispatch already provides. The Run workflow branch selector sets github.ref, and actions/checkout with no `ref:` defaults to it, so the branch dropdown is now the single source of truth for what gets built. Removes the footgun of dispatching from one branch while building another. Also drops `repository: startreedata/vector` from the checkout steps -- with git_ref gone it was redundant, and naming a repository explicitly changes how checkout resolves a missing ref. tag_latest removed; :latest is now always pushed alongside the versioned tag, matching startree-dex's st-release.yml. `push: false` still covers dry runs. concurrency, the Cargo.toml mismatch warning, and the run summary now use github.ref_name. Co-Authored-By: Claude Opus 5 (1M context) --- .../workflows/startree-distroless-build.yml | 47 ++----------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/.github/workflows/startree-distroless-build.yml b/.github/workflows/startree-distroless-build.yml index 744c8ab5c3d74..6e890ffcc4456 100644 --- a/.github/workflows/startree-distroless-build.yml +++ b/.github/workflows/startree-distroless-build.yml @@ -1,37 +1,15 @@ --- -# StarTree-only workflow. Builds the forked Vector as a static musl binary and -# publishes it on gcr.io/distroless/static, which scans clean (0 CVEs) instead of -# the ~53-86 CVEs carried by the hand-rolled Ubuntu-based image. -# -# Replaces sections 2.1-2.5 of: -# https://startree.atlassian.net/wiki/spaces/CORTEXDATA/pages/1987543044/Re-sync+Vector.dev+on+the+startree+fork -# -# Release versioning follows the same scheme as startree-dex's st-release.yml: -# an upstream base version plus a StarTree build number. -# -# base_version 0.49.0 + build_number 1 -> v0.49.0-ST-1 -# -# Each release pushes that image tag (optionally :latest too) and creates a -# matching annotated git tag on the built commit. +# StarTree-only workflow. Builds the forked Vector as a distroless multiarch image. # # Required repository secrets: # STARTREE_REGISTRY_USERNAME - repo.startreedata.io login # STARTREE_REGISTRY_PASSWORD - repo.startreedata.io token/password -# -# The checkout steps name startreedata/vector explicitly, so this file works -# unchanged whether it lives in the fork or in a separate ops repo. name: Build StarTree Vector (distroless) on: workflow_dispatch: inputs: - git_ref: - description: "Branch, tag, or SHA of startreedata/vector to build" - required: true - # st-master is the StarTree integration branch: upstream + our patches. - # `master` is a pristine upstream mirror and will not build our features. - default: st-master base_version: description: "Upstream Vector version this release is based on, e.g. 0.49.0" required: true @@ -40,10 +18,6 @@ on: description: "StarTree build number. 0.49.0 + 1 -> v0.49.0-ST-1" required: true default: "1" - tag_latest: - description: "Also push the :latest tag" - type: boolean - default: true push: description: "Push to the registry (uncheck for a build-only dry run)" type: boolean @@ -54,7 +28,7 @@ permissions: contents: write concurrency: - group: startree-distroless-${{ inputs.git_ref }} + group: startree-distroless-${{ github.ref }} cancel-in-progress: false env: @@ -76,8 +50,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - repository: startreedata/vector - ref: ${{ inputs.git_ref }} # Needed so the tag-existence check below sees existing tags. fetch-depth: 0 @@ -93,7 +65,7 @@ jobs: # upstream version -- the ST suffix belongs to the image tag only. CARGO_VERSION="$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)" if [ "$VERSION" != "$CARGO_VERSION" ]; then - echo "::warning::base_version ($VERSION) does not match Cargo.toml ($CARGO_VERSION) on ${{ inputs.git_ref }}" + echo "::warning::base_version ($VERSION) does not match Cargo.toml ($CARGO_VERSION) on ${{ github.ref_name }}" fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" @@ -102,7 +74,7 @@ jobs: { echo "image_tags<> "$GITHUB_OUTPUT" @@ -142,9 +114,6 @@ jobs: VERSION: ${{ needs.metadata.outputs.version }} steps: - uses: actions/checkout@v4 - with: - repository: startreedata/vector - ref: ${{ inputs.git_ref }} # A clean Vector release build needs ~30 GB; hosted runners ship ~14 GB free # on /. Without this the build dies partway through with ENOSPC. @@ -203,9 +172,6 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 - with: - repository: startreedata/vector - ref: ${{ inputs.git_ref }} # Both tarballs land in one context dir. The Dockerfile COPYs both and # extracts whichever matches `cat /etc/apk/arch` on the build platform. @@ -258,9 +224,6 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v4 - with: - repository: startreedata/vector - ref: ${{ inputs.git_ref }} # Tagged only after publish succeeds, so a failed build never leaves an # orphan release tag behind. @@ -281,7 +244,7 @@ jobs: echo echo "| | |" echo "|---|---|" - echo "| Built from | \`${{ inputs.git_ref }}\` |" + echo "| Built from | \`${{ github.ref_name }}\` |" echo "| Upstream base | \`${{ inputs.base_version }}\` |" echo "| StarTree build | \`${{ inputs.build_number }}\` |" echo