Skip to content

v2

v2 #3

Workflow file for this run

name: Release
on:
# Trigger on push to main for Release PR creation/update
push:
branches:
- main
# Trigger on PR events for dry-run checks
pull_request:
types:
- opened
- synchronize
branches:
- main
- "release/v*"
# Manual trigger for emergency releases
workflow_dispatch:
inputs:
force_release:
description: "Force a release even if no changes"
required: false
type: boolean
default: true
concurrency:
group: release-${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
env:
GO_VERSION: "1.26.1"
INITIAL_VERSION: "v0.1.0"
NODE_VERSION: "22"
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
PR_RELEASE_MODULE: github.com/productize/releasepr@v0.0.21
permissions:
contents: write
packages: write
pull-requests: write
id-token: write
attestations: write
jobs:
# Job 1: Create or update Release PR
release-pr:
name: Create/Update Release PR
if: |
(github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
!contains(github.event.head_commit.message, 'release:') &&
!startsWith(github.event.head_commit.message, 'ci(release):') &&
!startsWith(github.event.head_commit.message, 'Merge pull request') &&
github.event.head_commit.author.name != 'github-actions[bot]') ||
(github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Prepare Go temporary directory
env:
GOTMPDIR: ${{ runner.temp }}/go-tmp
run: mkdir -p "$GOTMPDIR"
- uses: ./.github/actions/setup-go
with:
go-version: ${{ env.GO_VERSION }}
install-tools: "false"
- uses: ./.github/actions/setup-node
- uses: ./.github/actions/setup-git-cliff
- name: Run PR Release Orchestrator
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
INITIAL_VERSION: ${{ env.INITIAL_VERSION }}
GOTMPDIR: ${{ runner.temp }}/go-tmp
run: |
go run "${{ env.PR_RELEASE_MODULE }}" pr-release --force --enable-rollback --ci-output
# Job 2: Dry-run checks on Release PR
dry-run:
name: Dry-Run Release Check
if: |
github.event_name == 'pull_request' &&
(startsWith(github.event.pull_request.title, 'ci(release): Release ') ||
startsWith(github.event.pull_request.title, 'release: Release ') ||
startsWith(github.base_ref, 'release/v'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Prepare Go temporary directory
env:
GOTMPDIR: ${{ runner.temp }}/go-tmp
run: mkdir -p "$GOTMPDIR"
- uses: ./.github/actions/setup-go
with:
go-version: ${{ env.GO_VERSION }}
install-tools: false
- uses: ./.github/actions/setup-node
- name: Setup Release Tools
uses: ./.github/actions/setup-release
with:
goreleaser-distribution: goreleaser
setup-docker: false
setup-docker-login: false
- name: Run Dry-Run Orchestrator
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_ISSUE_NUMBER: ${{ github.event.pull_request.number }}
GOTMPDIR: ${{ runner.temp }}/go-tmp
run: go run "${{ env.PR_RELEASE_MODULE }}" dry-run --ci-output
# Job 3: Production release on merge
release:
name: Production Release
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
(contains(github.event.head_commit.message, 'ci(release):') ||
startsWith(github.event.head_commit.message, 'release:'))
runs-on: ubuntu-latest
timeout-minutes: 120
env:
DOCKER_CLI_EXPERIMENTAL: enabled
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Prepare Go temporary directory
env:
GOTMPDIR: ${{ runner.temp }}/go-tmp
run: mkdir -p "$GOTMPDIR"
- name: Set up Go with caching
uses: ./.github/actions/setup-go
with:
go-version: ${{ env.GO_VERSION }}
install-tools: "true"
- uses: ./.github/actions/setup-node
- name: Setup Release Tools
uses: ./.github/actions/setup-release
with:
goreleaser-distribution: goreleaser
setup-docker: false
setup-docker-login: false
cosign-version: "v2.2.4"
- name: Create Git Tag
id: release-version
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
# Use git-cliff to get the bumped version
VERSION=$(git cliff --bumped-version 2>/dev/null | sed 's/^v//')
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v$VERSION" -m "Release v$VERSION"
git push origin "v$VERSION"
echo "Created and pushed tag v$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
else
echo "Could not get version from git-cliff. Got: $VERSION"
echo "Fallback: Extract from commit message"
VERSION=$(git log -1 --pretty=format:"%s" | sed -E 's/.*Release v([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v$VERSION" -m "Release v$VERSION"
git push origin "v$VERSION"
echo "Created and pushed tag v$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
else
echo "Could not extract version from any source. Got: $VERSION"
exit 1
fi
fi
- uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: ~> v2
args: >-
release --clean
--release-header-tmpl=.goreleaser.release-header.md.tmpl
--release-footer-tmpl=.goreleaser.release-footer.md.tmpl
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
COSIGN_EXPERIMENTAL: 1
GOTMPDIR: ${{ runner.temp }}/go-tmp
- name: Build npm CLI package
run: >-
node npm/cli/prepare-package.mjs
--version "${{ steps.release-version.outputs.version }}"
--dist dist
--out dist/npm/@productize/cli
- name: Publish npm CLI package
run: npm publish dist/npm/@productize/cli --access public