# Cuts a BCQuality content release on demand (roughly monthly), NOT on every # commit. Run this workflow manually once the `main` content is ready, and choose # whether to bump the minor (usual periodic content update) or the major # (breaking change). # # The version is a `major.minor` value derived from existing git tags — there is # no VERSION file. The minor is a monotonic counter: it only ever increments and # never resets, even across a major bump, so it uniquely identifies a release. # This workflow computes the next version and tags the current commit as # `v{major}.{minor}`. name: Release version on: workflow_dispatch: inputs: bump: description: Which part to bump type: choice options: - minor - major default: minor # Only tag creation needs write. permissions: contents: write concurrency: group: release-version cancel-in-progress: false jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Compute and tag release shell: bash run: | git fetch --tags --force --quiet tags="$(git tag -l | grep -E '^v[0-9]+\.[0-9]+$' || true)" if [[ -z "$tags" ]]; then # First release. major=1 minor=0 else latest_major="$(printf '%s\n' "$tags" | sed -E 's/^v([0-9]+)\..*/\1/' | sort -n | tail -1)" latest_minor="$(printf '%s\n' "$tags" | sed -E 's/^v[0-9]+\.([0-9]+)$/\1/' | sort -n | tail -1)" minor=$(( latest_minor + 1 )) # monotonic, never resets if [[ "${{ inputs.bump }}" == "major" ]]; then major=$(( latest_major + 1 )) else major="$latest_major" fi fi tag="v${major}.${minor}" if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then echo "::error::Tag ${tag} already exists" exit 1 fi git tag "$tag" "${{ github.sha }}" git push origin "$tag" echo "Released BCQuality ${tag} at ${{ github.sha }}"