← Files Dataiku HeadlessARCHIVED FILE
.github/workflows/bump.yml
7.63 KB · Nov 3, 2026 · 19:02 UTC
name: Bump version
# Collect changes on release/X.Y.Z, then finalize that branch with Commitizen.
# Publishing is a separate manual dispatch targeting that PR's merged commit.
on:
workflow_dispatch:
inputs:
operation:
description: Prepare a release PR or publish a merged release PR
type: choice
options: [prepare, publish]
default: prepare
required: true
release_branch:
description: Existing release/X.Y.Z branch to finalize (required for prepare)
type: string
default: ''
release_pr:
description: Merged release PR number (required for publish)
type: string
default: ''
concurrency:
group: bump
cancel-in-progress: false
permissions:
contents: read
jobs:
prepare:
if: github.ref == 'refs/heads/main' && inputs.operation == 'prepare'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Validate release branch input
env:
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
[[ "$RELEASE_BRANCH" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo 'Provide an existing release/X.Y.Z branch.'; exit 1; }
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.release_branch }}
fetch-depth: 0
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- name: Check release baseline
env:
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
set -euo pipefail
current=$(python3 scripts/check_release.py)
python3 scripts/check_release.py --target-branch "$RELEASE_BRANCH"
git merge-base --is-ancestor "refs/tags/v$current" HEAD
git merge-base --is-ancestor origin/main HEAD || { echo 'Merge main into the release branch first.'; exit 1; }
if git show-ref --verify --quiet "refs/tags/v${RELEASE_BRANCH#release/}"; then
echo 'The target version already has a tag.'
exit 1
fi
- name: Verify PEP 723 script lockfile is current
run: |
set -euo pipefail
uv lock --script runtime/run_mcp.py --check
uv lock --script runtime/run_mcp.py --upgrade
git diff --exit-code -- runtime/run_mcp.py.lock
- name: Finalize version and changelog locally
env:
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
set -euo pipefail
uv sync --locked
# The branch name is the intended version; Commitizen still owns the
# version-file updates and conventional-commit changelog generation.
uv run cz bump "${RELEASE_BRANCH#release/}" --version-files-only --changelog
uv lock
uv sync --locked
test "$(python3 scripts/check_release.py)" = "${RELEASE_BRANCH#release/}"
python3 scripts/check_release.py --notes > "$RUNNER_TEMP/notes.md"
- name: Open finalization PR into the release branch
env:
GH_TOKEN: ${{ github.token }}
RELEASE_BRANCH: ${{ inputs.release_branch }}
run: |
set -euo pipefail
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
version="${RELEASE_BRANCH#release/}"
git add --update
git commit -m "bump: finalize $version"
branch="prepare-release/$version"
# Neither protected integration branch is written directly. A
# non-fast-forward push fails rather than replacing a previous run.
git push origin "HEAD:refs/heads/$branch"
url=$(gh pr create --base "$RELEASE_BRANCH" --head "$branch" --title "bump: finalize $version" --body-file "$RUNNER_TEMP/notes.md")
echo "Finalization PR: $url. Approve workflows, review and merge. Then open $RELEASE_BRANCH into main and use a merge commit." >> "$GITHUB_STEP_SUMMARY"
publish:
if: github.ref == 'refs/heads/main' && inputs.operation == 'publish'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: read
actions: read
steps:
- name: Resolve merged release PR and check CI
id: target
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ inputs.release_pr }}
run: |
set -euo pipefail
[[ "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]] || { echo 'Provide a release PR number.'; exit 1; }
gh api "repos/$GH_REPO/pulls/$PR_NUMBER" > "$RUNNER_TEMP/pr.json"
jq -e --arg repo "$GH_REPO" '.merged == true and .base.ref == "main" and .head.repo.full_name == $repo and (.head.ref | test("^release/[0-9]+\\.[0-9]+\\.[0-9]+$"))' "$RUNNER_TEMP/pr.json"
sha=$(jq -r .merge_commit_sha "$RUNNER_TEMP/pr.json")
version=$(jq -r '.head.ref | ltrimstr("release/")' "$RUNNER_TEMP/pr.json")
gh api "repos/$GH_REPO/actions/workflows/ci.yml/runs?head_sha=$sha&event=push&per_page=1" > "$RUNNER_TEMP/ci.json"
jq -e '.workflow_runs[0] | .status == "completed" and .conclusion == "success"' "$RUNNER_TEMP/ci.json"
echo "head_sha=$(jq -r .head.sha "$RUNNER_TEMP/pr.json")" >> "$GITHUB_OUTPUT"
echo "sha=$sha" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ steps.target.outputs.sha }}
fetch-depth: 0
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
- name: Verify merged release before publishing
env:
VERSION: ${{ steps.target.outputs.version }}
RELEASE_HEAD: ${{ steps.target.outputs.head_sha }}
run: |
set -euo pipefail
python3 scripts/check_release.py --merge-head "$RELEASE_HEAD"
test "$(python3 scripts/check_release.py)" = "$VERSION"
git merge-base --is-ancestor HEAD origin/main
uv lock --check
uv lock --script runtime/run_mcp.py --check
python3 scripts/check_release.py --notes > "$RUNNER_TEMP/notes.md"
- name: Push matching tags and publish release
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.target.outputs.version }}
run: |
set -euo pipefail
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
sha=$(git rev-parse HEAD)
# Check BOTH existing tags before creating or pushing either one.
for tag in "v$VERSION" "dataiku-headless--v$VERSION"; do
if git show-ref --verify --quiet "refs/tags/$tag"; then
test "$(git rev-parse "refs/tags/$tag^{commit}")" = "$sha" || { echo "Tag $tag points to another commit."; exit 1; }
fi
done
for tag in "v$VERSION" "dataiku-headless--v$VERSION"; do
git show-ref --verify --quiet "refs/tags/$tag" || git tag -a "$tag" -m "dataiku-headless $VERSION"
done
git push --atomic origin "refs/tags/v$VERSION" "refs/tags/dataiku-headless--v$VERSION"
# A successful retry leaves an existing release unchanged.
gh release list --limit 1000 --json tagName > "$RUNNER_TEMP/releases.json"
if ! jq -e --arg tag "v$VERSION" 'any(.[]; .tagName == $tag)' "$RUNNER_TEMP/releases.json"; then
gh release create "v$VERSION" --verify-tag --title "v$VERSION" --notes-file "$RUNNER_TEMP/notes.md"
fi
gh release view "v$VERSION" --json url --jq .url >> "$GITHUB_STEP_SUMMARY"
SHA-256: 7a1bab86b7f396cd78b81bc1a41a51e89dac38de8920d4838ceb82c22f1d19b3