Skip to content

Latest commit

 

History

History
482 lines (365 loc) · 10.9 KB

File metadata and controls

482 lines (365 loc) · 10.9 KB

Release Workflow

Reusable workflow for semantic versioning and automated release management. Creates releases based on conventional commits and manages version tags with GPG signing.

Features

  • Semantic versioning: Automatic version calculation from conventional commits
  • GPG signing: Signed commits and tags for security
  • GitHub App authentication: Higher rate limits and better security
  • Hotfix support: Separate configuration for hotfix branches
  • Backmerge support: Automatic backmerging of releases (falls back to creating a PR if the direct push fails due to branch divergence)
  • Conventional commits: Enforces commit message standards

Usage

Basic Example

name: Release Pipeline
on:
  push:
    branches:
      - develop
      - release-candidate
      - main

jobs:
  release:
    uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
    secrets: inherit

Required Secrets: LERIAN_STUDIO_MIDAZ_PUSH_BOT_APP_ID, LERIAN_STUDIO_MIDAZ_PUSH_BOT_PRIVATE_KEY, LERIAN_CI_CD_USER_GPG_KEY, LERIAN_CI_CD_USER_GPG_KEY_PASSWORD, LERIAN_CI_CD_USER_NAME, LERIAN_CI_CD_USER_EMAIL

With Custom Runner

release:
  uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
  with:
    runner_type: "blacksmith-4vcpu-ubuntu-2404"
    semantic_version: "23.0.8"
  secrets: inherit

Complete Release Pipeline

name: Release Pipeline
on:
  push:
    branches:
      - develop
      - release-candidate
      - main
    paths-ignore:
      - '**/*.md'
      - '**/*.txt'
      - '**/*.env'

permissions:
  id-token: write
  contents: write
  pull-requests: write

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: make test

  release:
    needs: tests
    uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
    secrets: inherit

Inputs

Input Type Default Description
semantic_version string 23.0.8 Semantic release version to use
runner_type string firmino-lxc-runners GitHub runner type

Secrets

Required Secrets

Secret Description
lerian_studio_push_bot_app_id GitHub App ID for authentication
lerian_studio_push_bot_private_key GitHub App private key
lerian_ci_cd_user_gpg_key GPG private key for signing commits
lerian_ci_cd_user_gpg_key_password GPG key passphrase
lerian_ci_cd_user_name Git committer name
lerian_ci_cd_user_email Git committer email

Outputs

Output Description
gpg_fingerprint GPG key fingerprint used for signing

Branch Strategy

develop → Beta Releases

Commits to develop branch create beta releases:

  • Version: v1.2.3-beta.1
  • Pre-release: Yes
  • Use case: Development testing

release-candidate → RC Releases

Commits to release-candidate branch create RC releases:

  • Version: v1.2.3-rc.1
  • Pre-release: Yes
  • Use case: Staging/UAT testing

main → Production Releases

Commits to main branch create production releases:

  • Version: v1.2.3
  • Pre-release: No
  • Use case: Production deployment

Configuration

The workflow uses .releaserc.yml for all branches (no separate hotfix configuration).

Configuration file: .releaserc.yml in repository root

Conventional Commits

The workflow uses conventional commits to determine version bumps:

Breaking Changes (Major)

feat!: remove deprecated API endpoint

BREAKING CHANGE: The /api/v1/old endpoint has been removed

Version: 1.0.02.0.0

Features (Minor)

feat: add user authentication

Version: 1.0.01.1.0

Fixes (Patch)

fix: resolve memory leak in transaction processor

Version: 1.0.01.0.1

Other Types (No Version Bump)

docs: update API documentation
chore: update dependencies
style: fix code formatting
refactor: simplify authentication logic
perf: optimize database queries
test: add unit tests for auth module
ci: update GitHub Actions workflow

No version bump, but included in changelog.

Configuration File Example

.releaserc.yml

Single configuration file for all branches:

branches:
  - name: main
  - name: release-candidate
    prerelease: rc
  - name: develop
    prerelease: beta

plugins:
  - - "@semantic-release/commit-analyzer"
    - preset: conventionalcommits
      releaseRules:
        - type: feat
          release: minor
        - type: fix
          release: patch
        - type: perf
          release: patch
        - breaking: true
          release: major
  - "@semantic-release/release-notes-generator"
  - "@semantic-release/changelog"
  - "@semantic-release/github"
  - - "@saithodev/semantic-release-backmerge"
    - backmergeBranches: [develop]
      backmergeStrategy: merge

Workflow Steps

  1. Create GitHub App Token: Generate authentication token with higher rate limits
  2. Checkout Repository: Clone with full history for versioning
  3. Sync with Remote: Ensure latest changes are pulled
  4. Import GPG Key: Import and configure GPG key for signing
  5. Initialize package.json: Create if doesn't exist
  6. Install Plugins: Install semantic-release plugins
  7. Run Semantic Release: Calculate version and create release using .releaserc.yml

GPG Signing

Why GPG Signing?

  • Authenticity: Verify commits are from authorized sources
  • Integrity: Ensure commits haven't been tampered with
  • Compliance: Meet security requirements for production releases

Setup GPG Key

  1. Generate GPG key:
gpg --full-generate-key
  1. Export private key:
gpg --armor --export-secret-keys YOUR_EMAIL > private-key.asc
  1. Add to GitHub Secrets:
  • GPG_PRIVATE_KEY: Contents of private-key.asc
  • GPG_KEY_PASSWORD: Key passphrase
  1. Add public key to GitHub:
gpg --armor --export YOUR_EMAIL

Add to GitHub Settings → SSH and GPG keys

GitHub App Setup

Why GitHub App?

  • Higher rate limits: 5,000 requests/hour vs 1,000 for PAT
  • Better security: Scoped permissions, automatic token expiration
  • Audit trail: Better tracking of automated actions

Create GitHub App

  1. Go to GitHub Settings → Developer settings → GitHub Apps
  2. Click "New GitHub App"
  3. Configure:
    • Name: My CI/CD Bot
    • Homepage URL: Your organization URL
    • Permissions:
      • Contents: Read & Write
      • Pull Requests: Read & Write
      • Metadata: Read-only
  4. Generate private key
  5. Install app to repositories
  6. Add to secrets:
    • GITHUB_APP_ID: App ID
    • GITHUB_APP_PRIVATE_KEY: Private key contents

Best Practices

1. Use Conventional Commits

Enforce with commitlint:

# .commitlintrc.yml
extends:
  - '@commitlint/config-conventional'
rules:
  type-enum:
    - 2
    - always
    - [feat, fix, docs, style, refactor, perf, test, chore, revert, ci, build]

2. Protect Release Branches

Configure branch protection:

  • Require pull request reviews
  • Require status checks to pass
  • Require signed commits
  • Include administrators

3. Use Environment Protection

jobs:
  release:
    environment:
      name: production

Add required reviewers for production releases.

4. Ignore Non-code Changes

on:
  push:
    paths-ignore:
      - '**/*.md'
      - '**/*.txt'
      - '**/*.env'

5. Run Tests Before Release

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - name: Run tests
        run: make test

  release:
    needs: tests

Troubleshooting

Release Not Created

Issue: Workflow runs but no release is created

Solutions:

  1. Check commit messages follow conventional commits
  2. Verify branch is configured in .releaserc
  3. Check if version already exists
  4. Review semantic-release logs

GPG Signing Failed

Issue: Cannot sign commits with GPG key

Solutions:

  1. Verify GPG key is valid: gpg --list-secret-keys
  2. Check passphrase is correct
  3. Ensure key hasn't expired
  4. Verify key format (ASCII armored)

Authentication Failed

Issue: Cannot push tags or create releases

Solutions:

  1. Verify GitHub App is installed on repository
  2. Check App permissions (Contents: Write)
  3. Verify App ID and private key are correct
  4. Ensure App token hasn't expired

Wrong Version Calculated

Issue: Semantic release calculates incorrect version

Solutions:

  1. Check commit message format
  2. Verify branch configuration in .releaserc
  3. Review previous tags: git tag -l
  4. Check for BREAKING CHANGE in commit body

Hotfix Configuration Not Used

Issue: Hotfix branch uses wrong configuration

Solutions:

  1. Verify branch name matches hotfix/* pattern
  2. Check .releaserc.hotfix exists
  3. Review workflow step logs

Examples

Basic Release Workflow

name: Release
on:
  push:
    branches: [develop, release-candidate, main]

jobs:
  release:
    uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
    secrets: inherit

Release with Build Pipeline

name: Release Pipeline
on:
  push:
    branches: [develop, release-candidate, main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: make test

  release:
    needs: test
    uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
    secrets: inherit

  build:
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build and push
        run: make build-push

Hotfix Workflow

name: Hotfix Release
on:
  push:
    branches:
      - 'hotfix/**'

jobs:
  release:
    uses: LerianStudio/github-actions-shared-workflows/.github/workflows/release.yml@v1.0.0
    secrets: inherit

Semantic Release Plugins

Included Plugins

  • @semantic-release/commit-analyzer: Analyzes commits to determine version bump
  • @semantic-release/release-notes-generator: Generates release notes from commits
  • @semantic-release/github: Creates GitHub releases
  • @semantic-release/exec: Executes custom scripts (installed automatically)
  • conventional-changelog-conventionalcommits: Conventional commits support
  • @saithodev/semantic-release-backmerge: Automatic backmerging

Custom Plugins

Add custom plugins in .releaserc:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    "@semantic-release/npm",
    "@semantic-release/github",
    "@semantic-release/git"
  ]
}

Related Workflows