Skip to content

Publish verified Boatstack release #471

Publish verified Boatstack release

Publish verified Boatstack release #471

Workflow file for this run

# Boatstack-owned control plane.
name: Publish verified Boatstack release
on:
workflow_run:
workflows: ["CI"]
types: [completed]
permissions:
contents: read
concurrency:
group: auto-release-boatstack
cancel-in-progress: false
jobs:
release:
if: >-
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push' &&
github.event.workflow_run.head_branch == 'main'
runs-on: ubuntu-latest
steps:
- name: Create repository automation token
id: app-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.BOATSTACK_APP_CLIENT_ID }}
private-key: ${{ secrets.BOATSTACK_APP_PRIVATE_KEY }}
owner: operatorstack
repositories: boatstack
permission-contents: write
- uses: actions/checkout@v7
with:
ref: main
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Detect release-bearing change
id: classify
shell: bash
run: |
latest_tag="$(git describe --tags --abbrev=0 --match 'v[0-9]*' 2>/dev/null || true)"
if [[ -z "$latest_tag" ]]; then
echo "BLOCKED: automatic patch releases require an existing stable tag." >&2
exit 1
fi
rewritten="$(git diff --name-only --diff-filter=MD --no-renames "$latest_tag" HEAD -- 'release-notes/*.md')"
if [[ -n "$rewritten" ]]; then
echo "BLOCKED: release notes are append-only:" >&2
printf ' %s\n' "$rewritten" >&2
exit 1
fi
added="$(git diff --name-only --diff-filter=A --no-renames "$latest_tag" HEAD -- 'release-notes/*.md')"
if [[ -n "$added" ]]; then
echo "release_required=true" >> "$GITHUB_OUTPUT"
else
echo "release_required=false" >> "$GITHUB_OUTPUT"
fi
echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT"
- name: Create next verified patch tag
if: steps.classify.outputs.release_required == 'true'
env:
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
LATEST_TAG: ${{ steps.classify.outputs.latest_tag }}
shell: bash
run: |
version="${LATEST_TAG#v}"
IFS=. read -r major minor patch <<< "$version"
if [[ ! "$major" =~ ^[0-9]+$ || ! "$minor" =~ ^[0-9]+$ || ! "$patch" =~ ^[0-9]+$ ]]; then
echo "BLOCKED: latest tag is not a stable semantic version: $LATEST_TAG" >&2
exit 1
fi
next_tag="v${major}.${minor}.$((patch + 1))"
if git rev-parse --verify --quiet "refs/tags/$next_tag"; then
echo "BLOCKED: tag already exists: $next_tag" >&2
exit 1
fi
git config user.name "${APP_SLUG}[bot]"
git config user.email "${APP_SLUG}[bot]@users.noreply.github.com"
git tag -a "$next_tag" -m "Boatstack $next_tag"
git push origin "$next_tag"
echo "Published verified release tag $next_tag."
- name: Report documentation-only sync
if: steps.classify.outputs.release_required != 'true'
run: echo "Boatstack content is current; this merge does not require new binaries."