Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/actions/create-release-tag/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Compute the next version tag, create it, and push it.

inputs:
bump:
description: Version bump type (patch or minor)
description: Version bump type (patch, minor, or major)
required: true

outputs:
Expand All @@ -28,23 +28,31 @@ runs:
run: |
set -euo pipefail

latest="$(git tag --list "v0.*.*" --sort=-v:refname | grep -E "^v0\.[0-9]+\.[0-9]+$" | head -n 1 || true)"
latest="$(git tag --list "v*.*.*" --sort=-v:refname | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$" | head -n 1 || true)"
if [[ -z "${latest}" ]]; then
major=0
minor=1
patch=0
else
current_major="$(echo "${latest}" | cut -d. -f1 | tr -d 'v')"
current_minor="$(echo "${latest}" | cut -d. -f2)"
current_patch="$(echo "${latest}" | cut -d. -f3)"
if [[ "${BUMP}" == "minor" ]]; then
if [[ "${BUMP}" == "major" ]]; then
major="$(( current_major + 1 ))"
minor=0
patch=0
elif [[ "${BUMP}" == "minor" ]]; then
major="${current_major}"
minor="$(( current_minor + 1 ))"
patch=0
else
major="${current_major}"
minor="${current_minor}"
patch="$(( current_patch + 1 ))"
fi
fi

tag="v0.${minor}.${patch}"
tag="v${major}.${minor}.${patch}"
if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
echo "Tag ${tag} already exists"
exit 1
Expand Down
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ updates:
time: "09:00"
timezone: "Etc/UTC"
open-pull-requests-limit: 10
labels:
- "semver: patch"

- package-ecosystem: "github-actions"
directory: "/"
Expand All @@ -15,3 +17,5 @@ updates:
time: "10:00"
timezone: "Etc/UTC"
open-pull-requests-limit: 10
labels:
- "semver: patch"
62 changes: 59 additions & 3 deletions .github/workflows/automated-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
run: |
set -euo pipefail

latest_tag="$(git tag --list "v0.*.*" --sort=-v:refname | grep -E "^v0\.[0-9]+\.[0-9]+$" | head -n 1 || true)"
latest_tag="$(git tag --list "v*.*.*" --sort=-v:refname | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$" | head -n 1 || true)"
if [[ -z "${latest_tag}" ]]; then
echo "No previous tag found, proceeding with release"
echo "has_changes=true" >> "${GITHUB_OUTPUT}"
Expand All @@ -51,6 +51,62 @@ jobs:
fi
fi

determine-bump:
name: Determine version bump
needs: check-changes
if: needs.check-changes.outputs.has_changes == 'true'
runs-on: ubuntu-latest
outputs:
bump: ${{ steps.bump.outputs.bump }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: main
fetch-depth: 0
token: ${{ secrets.PRO_ACCESS_TOKEN }}

- name: Fetch tags
run: git fetch --tags --force

- name: Determine bump type from PR labels
id: bump
env:
GH_TOKEN: ${{ secrets.PRO_ACCESS_TOKEN }}
run: |
set -euo pipefail

latest_tag="$(git tag --list "v*.*.*" --sort=-v:refname | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$" | head -n 1 || true)"

if [[ -z "${latest_tag}" ]]; then
echo "No previous tag found, defaulting to patch"
echo "bump=patch" >> "${GITHUB_OUTPUT}"
exit 0
fi

# Use git history to find exactly which PRs are part of this release
pr_numbers="$(git log "${latest_tag}..HEAD" --oneline | grep -oE '#[0-9]+' | tr -d '#' | sort -u)"

if [[ -z "${pr_numbers}" ]]; then
echo "No PRs found since ${latest_tag}, defaulting to patch"
echo "bump=patch" >> "${GITHUB_OUTPUT}"
exit 0
fi

bump="patch"
for pr in ${pr_numbers}; do
labels="$(gh pr view "${pr}" --json labels --jq '.labels[].name' 2>/dev/null || true)"
if echo "${labels}" | grep -q "semver: major"; then
bump="major"
break
elif echo "${labels}" | grep -q "semver: minor"; then
bump="minor"
fi
done

echo "Determined bump type: ${bump}"
echo "bump=${bump}" >> "${GITHUB_OUTPUT}"

ci:
name: CI
needs: check-changes
Expand All @@ -60,7 +116,7 @@ jobs:

create-tag:
name: Create release tag
needs: [check-changes, ci]
needs: [check-changes, determine-bump, ci]
if: needs.check-changes.outputs.has_changes == 'true'
runs-on: ubuntu-latest
steps:
Expand All @@ -77,4 +133,4 @@ jobs:
- name: Create release tag
uses: ./.github/actions/create-release-tag
with:
bump: patch
bump: ${{ needs.determine-bump.outputs.bump }}
19 changes: 19 additions & 0 deletions .github/workflows/check-release-label.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Require release label

on:
pull_request:
types: [opened, labeled, unlabeled, synchronize, reopened]

jobs:
check-label:
name: Require release label
runs-on: ubuntu-latest
steps:
- name: Check for semver label
env:
LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
if ! echo "${LABELS}" | jq -e 'any(. == "semver: patch" or . == "semver: minor" or . == "semver: major")' > /dev/null; then
echo "::error::PR must have a release label: 'semver: patch', 'semver: minor', or 'semver: major'"
exit 1
fi
Loading