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: 14 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,27 @@ jobs:
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-tag:
calculate-tag:
needs: determine-version
uses: ./.github/workflows/workflow-create-tag.yml
uses: ./.github/workflows/workflow-compute-next-tag.yml
with:
target-branch: main
version-bump: ${{ needs.determine-version.outputs.version-bump }}
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-tag:
needs:
- determine-version
- calculate-tag
uses: ./.github/workflows/workflow-create-tag.yml
with:
target-branch: main
next-tag: ${{ needs.calculate-tag.outputs.new-tag }}
previous-tag: ${{ needs.calculate-tag.outputs.previous-tag }}
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-release:
needs:
- determine-version
Expand Down
95 changes: 95 additions & 0 deletions .github/workflows/workflow-compute-next-tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Compute Next Tag

on:
workflow_call:
inputs:
target-branch:
description: "Branch to fetch before calculating the next tag."
required: false
default: main
type: string
version-bump:
description: "Which part of the semver should be incremented (major/minor/patch)."
required: true
type: string
secrets:
gh_token:
description: "Token passed from caller (defaults to the built-in GITHUB_TOKEN)."
required: false
outputs:
new-tag:
description: "Next tag derived from the latest v* tag and the selected bump."
value: ${{ jobs.calculate.outputs.new-tag }}
previous-tag:
description: "Latest tag used as the base for the next version."
value: ${{ jobs.calculate.outputs.previous-tag }}

permissions:
contents: read

jobs:
calculate:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
new-tag: ${{ steps.compute.outputs.new_tag }}
previous-tag: ${{ steps.compute.outputs.previous_tag }}
steps:
- name: Check out repository with tags
uses: actions/checkout@v4
with:
ref: ${{ inputs.target-branch }}
fetch-depth: 0

- name: Compute next tag
id: compute
env:
VERSION_BUMP_INPUT: ${{ inputs.version-bump }}
run: |
set -euo pipefail

version_bump="${VERSION_BUMP_INPUT,,}"
case "$version_bump" in
major|minor|patch) ;;
*)
echo "Unsupported version bump '$version_bump'."
exit 1
;;
esac

git fetch --tags

latest_tag=$(git tag --list 'v*' --sort=-v:refname | head -n1)
if [ -z "$latest_tag" ]; then
latest_tag="v0.0.0"
fi
previous_tag="$latest_tag"

version="${latest_tag#v}"
IFS='.' read -r major minor patch <<<"$version"
major=${major:-0}
minor=${minor:-0}
patch=${patch:-0}

case "$version_bump" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac

new_tag="v${major}.${minor}.${patch}"

{
echo "new_tag=$new_tag"
echo "previous_tag=$previous_tag"
} >> "$GITHUB_OUTPUT"
54 changes: 17 additions & 37 deletions .github/workflows/workflow-create-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ on:
required: false
default: main
type: string
version-bump:
description: "Which part of the semver should be incremented (major/minor/patch)."
next-tag:
description: "Explicit tag to create (required)."
required: true
type: string
previous-tag:
description: "Previously released tag that the next tag is based on (required)."
required: true
type: string
secrets:
Expand Down Expand Up @@ -42,7 +46,8 @@ jobs:
- name: Create and push tag
id: create
env:
VERSION_BUMP_INPUT: ${{ inputs.version-bump }}
NEXT_TAG_INPUT: ${{ inputs.next-tag }}
PREVIOUS_TAG_INPUT: ${{ inputs.previous-tag }}
TARGET_BRANCH_INPUT: ${{ inputs.target-branch }}
GH_TOKEN: ${{ secrets.gh_token != '' && secrets.gh_token || secrets.GITHUB_TOKEN }}
run: |
Expand All @@ -51,48 +56,23 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

version_bump="${VERSION_BUMP_INPUT,,}"
case "$version_bump" in
major|minor|patch) ;;
*)
echo "Unsupported version bump '$version_bump'."
exit 1
;;
esac

git fetch origin "$TARGET_BRANCH_INPUT" --tags
git checkout "$TARGET_BRANCH_INPUT"
git pull origin "$TARGET_BRANCH_INPUT"

latest_tag=$(git tag --list 'v*' --sort=-v:refname | head -n1)
if [ -z "$latest_tag" ]; then
latest_tag="v0.0.0"
next_tag_input="${NEXT_TAG_INPUT:-}"
previous_tag_input="${PREVIOUS_TAG_INPUT:-}"

if [ -z "$next_tag_input" ] || [ -z "$previous_tag_input" ]; then
echo "Both next-tag and previous-tag inputs are required."
exit 1
fi
previous_tag="$latest_tag"
version="${latest_tag#v}"
IFS='.' read -r major minor patch <<<"$version"
major=${major:-0}
minor=${minor:-0}
patch=${patch:-0}

case "$version_bump" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac
new_tag="$next_tag_input"
previous_tag="$previous_tag_input"

new_tag="v${major}.${minor}.${patch}"
echo "Creating tag $new_tag (previous tag $previous_tag)."
git tag -a "$new_tag" -m "Automated $version_bump release"
git tag -a "$new_tag" -m "Automated release $new_tag"
git push origin "$new_tag"

echo "::notice title=Tag created::${new_tag} (from ${previous_tag})"
Expand Down
46 changes: 41 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,46 @@ jobs:
```

### `workflow-create-tag.yml`
Creates and pushes the next semver tag based on the provided bump.
Creates and pushes the provided tag (no version calculation inside this workflow).

**Inputs**
- `target-branch` (default `main`): branch to check out before tagging.
- `version-bump` (required): `major`, `minor`, or `patch`.
- `next-tag` (required): tag to create (e.g., `v1.2.3`).
- `previous-tag` (required): previous tag that `next-tag` is based on.

**Outputs**
- `new-tag`: tag that was created (e.g., `v1.2.3`).
- `previous-tag`: latest existing tag before the bump.
- `previous-tag`: previous tag that was passed in.

**Example**
```yaml
jobs:
create-tag:
uses: vinitu-net/github-workflows/.github/workflows/workflow-create-tag.yml@vX.Y.Z
with:
target-branch: main
next-tag: ${{ needs.calculate-tag.outputs.new-tag }}
previous-tag: ${{ needs.calculate-tag.outputs.previous-tag }}
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}
```

### `workflow-compute-next-tag.yml`
Calculates the next semver tag from the provided bump and latest existing `v*` tag.

**Inputs**
- `target-branch` (default `main`): branch to check out before reading tags.
- `version-bump` (required): `major`, `minor`, or `patch`.

**Outputs**
- `new-tag`: computed next tag (e.g., `v1.2.3`).
- `previous-tag`: latest existing tag before the bump (or `v0.0.0` if none).

**Example**
```yaml
jobs:
calculate-tag:
uses: vinitu-net/github-workflows/.github/workflows/workflow-compute-next-tag.yml@vX.Y.Z
with:
target-branch: main
version-bump: ${{ needs.determine-version.outputs.version-bump }}
Expand Down Expand Up @@ -134,16 +159,27 @@ jobs:
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-tag:
calculate-tag:
needs: [determine-version, merge]
if: ${{ needs.merge.outputs.merged == 'true' }}
uses: vinitu-net/github-workflows/.github/workflows/workflow-create-tag.yml@vX.Y.Z
uses: vinitu-net/github-workflows/.github/workflows/workflow-compute-next-tag.yml@vX.Y.Z
with:
target-branch: main
version-bump: ${{ needs.determine-version.outputs.version-bump }}
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-tag:
needs: [determine-version, merge, calculate-tag]
if: ${{ needs.merge.outputs.merged == 'true' }}
uses: vinitu-net/github-workflows/.github/workflows/workflow-create-tag.yml@vX.Y.Z
with:
target-branch: main
next-tag: ${{ needs.calculate-tag.outputs.new-tag }}
previous-tag: ${{ needs.calculate-tag.outputs.previous-tag }}
secrets:
gh_token: ${{ secrets.GITHUB_TOKEN }}

create-release:
needs: [merge, create-tag]
if: ${{ needs.merge.outputs.merged == 'true' }}
Expand Down