Skip to content

chore: add tag + release + validate workflows (no third-party actions) #3

Description

@kameshsampath

Context

Add three GitHub Actions workflows to automate tagging, releasing, and
PR validation. All use only actions/checkout@v4 (GitHub-own) + pre-installed
gh CLI — no third-party actions. Patterns adapted from coco-for-developer-advocates.


tag.yml — auto-tag on push to main (replaces svu with pure shell)

name: Tag
on:
  push:
    branches: [main]
permissions:
  contents: write
jobs:
  tag:
    if: "!startsWith(github.event.head_commit.message, '[skip-release]')"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Compute and push next tag
        run: |
          PREV=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
          COMMITS=$(git log --pretty=format:"%s" ${PREV}..HEAD)
          if echo "$COMMITS" | grep -qE "^(feat|fix)!:|BREAKING CHANGE"; then
            BUMP=major
          elif echo "$COMMITS" | grep -q "^feat:"; then
            BUMP=minor
          else
            BUMP=patch
          fi
          MAJOR=$(echo $PREV | cut -d. -f1 | tr -d v)
          MINOR=$(echo $PREV | cut -d. -f2)
          PATCH=$(echo $PREV | cut -d. -f3)
          case "$BUMP" in
            major) MAJOR=$((MAJOR+1)); MINOR=0; PATCH=0 ;;
            minor) MINOR=$((MINOR+1)); PATCH=0 ;;
            patch) PATCH=$((PATCH+1)) ;;
          esac
          NEXT="v${MAJOR}.${MINOR}.${PATCH}"
          echo "Bumping $PREV → $NEXT ($BUMP)"
          git tag "$NEXT" && git push origin "$NEXT"

release.yml — tag push → GitHub Release with auto-generated notes

name: Release
on:
  push:
    tags: ['v*']
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to release (e.g. v0.1.0). Must already exist.'
        required: true
permissions:
  contents: write
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.tag || github.ref }}
      - name: Validate semver tag
        run: |
          REF="${{ github.event.inputs.tag || github.ref_name }}"
          VERSION="${REF#v}"
          if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
            echo "::error::Tag must be semver: vX.Y.Z (got $REF)"; exit 1
          fi
          echo "ref=$REF" >> "$GITHUB_ENV"
      - name: Create release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release create "$ref" --title "$ref" --generate-notes

validate.yml — PR conventional commit lint (pure shell, copied from coco-for-developer-advocates)

name: Validate
on: pull_request
jobs:
  commit-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Check conventional commits
        run: |
          ERRORS=0
          while read -r msg; do
            if ! echo "$msg" | grep -qE \
              '^(feat|fix|chore|docs|refactor|test|ci|perf|build|style)(\(.+\))?!?:'; then
              echo "::warning::Non-conventional commit: $msg"
              ERRORS=$((ERRORS + 1))
            fi
          done < <(git log --format='%s' origin/main..HEAD)
          [ "$ERRORS" -gt 0 ] && echo "::warning::$ERRORS non-conventional commit(s) found."

Timing

Add before Jun 16 so v0.1.0 tag triggers the first proper release automatically.
Use [skip-release] prefix on any commit that should not bump the version.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions