Skip to content

Latest commit

 

History

History
109 lines (95 loc) · 3.65 KB

File metadata and controls

109 lines (95 loc) · 3.65 KB

Release Scripts

The following scripts are exposed for use:

tagAndRelease

This script creates a Git tag and Github release for a given version. It is expected to be run as part of CI and only once for the given version defined in package.json.

Git tags and releases are created with the following naming scheme: v1.2.3. i.e. a v is prepended to the version defined in package.json.

Usage

It is recommended to:

  1. Create a script that imports and uses the tagAndRelease function as demonstrated below.
  2. Define a package.json script that triggers the release.
  3. Call that script as part of the CI process.
// scripts/tag-and-release.ts
import { join } from 'node:path';

import { tagAndRelease } from '@api3/commons';

const main = async () => {
  const packageJsonPath = join(__dirname, '../package.json'); // the script is one level deep in the repo
  await tagAndRelease('my-repo-name', packageJsonPath, 'optional-branch-name-if-not-main');
};

main()
  .then(() => process.exit(0))
  .catch((error: unknown) => {
    console.info(error);
    process.exitCode = 1;
  });

// package.json
{
  "scripts": {
    "release:tag": "ts-node scripts/tag-and-release.ts",
  }
}

It's also recommended to setup a step in CI that checks if the Git tag already exists before executing.

########################################################################################
# The following secrets are required:
#
# 1. GH_ACCESS_TOKEN - A "fine-grained personal access token" generated through the
#    Github UI. It seems like these tokens are scoped to a user, rather than an
#    organisation.
#
#    The following minimum permissions are required:
#      Read - access to metadata
#      Read & write - access to actions and code
# 2. GH_USER_NAME - The name (not username) associated with the Git user. e.g. John Smith
# 3. GH_USER_EMAIL - The email associated with the Git user
########################################################################################
tag-and-release:
  name: Tag and release
  runs-on: ubuntu-latest
  needs: required-checks-passed
  # Only tag and release on pushes to main
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'
  permissions:
    id-token: write # Required for https://docs.npmjs.com/trusted-publishers
    contents: write # Required for pushing tags and making the GitHub releases
  steps:
    - name: Clone repo
      uses: actions/checkout@v6
      with:
        fetch-depth: 0
    - name: Install pnpm
      uses: pnpm/action-setup@v3
    - name: Setup Node
      uses: actions/setup-node@v6
      with:
        node-version: 24
        registry-url: 'https://registry.npmjs.org'
        cache: 'pnpm'
    - name: Configure Git credentials
      run: |
        git config --global user.name '${{ secrets.GH_USER_NAME }}'
        git config --global user.email '${{ secrets.GH_USER_EMAIL }}'
    - name: Install Dependencies
      run: pnpm install --frozen-lockfile
    - name: Build
      run: pnpm run build
    - name: Get package.json version
      id: get-version
      run: echo "version=$(cat package.json | jq -r '.version' | sed 's/^/v/')" >> $GITHUB_OUTPUT
    - name: Validate tag
      id: validate-tag
      run:
        test "$(git tag -l '${{ steps.get-version.outputs.version }}' | awk '{print $NF}')" = "${{
        steps.get-version.outputs.version }}" || echo "new-tag=true" >> $GITHUB_OUTPUT
    - name: Tag and release on Github
      if: ${{ steps.validate-tag.outputs.new-tag }}
      run: pnpm run release:tag
      env:
        GH_ACCESS_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
    - name: Publish to npm
      if: ${{ steps.validate-tag.outputs.new-tag }}
      run: pnpm publish --access public