Release #28
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| pull_request: | |
| types: [closed] | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to source release notes + comment from (recovery path when pull_request trigger misfired)' | |
| required: false | |
| type: string | |
| default: '' | |
| permissions: | |
| contents: write | |
| id-token: write | |
| pull-requests: write | |
| concurrency: | |
| group: release | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| if: >- | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event.pull_request.merged && startsWith(github.head_ref, 'release')) | |
| runs-on: ubuntu-latest | |
| environment: Release | |
| env: | |
| COMPOSE_FILE: ./compose.yml | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Start Database Services | |
| run: docker compose up -d | |
| - name: Enable Corepack (pre-setup-node) | |
| # setup-node@v5 auto-probes `yarn cache dir` during setup; without corepack | |
| # enabled first, the probe hits the runner's global yarn 1.22 and fails | |
| # against our `packageManager: yarn@4.12.0` pin. Enable corepack on the | |
| # runner's system Node BEFORE setup-node switches Node versions. | |
| run: corepack enable | |
| - name: Setup Node.js | |
| # `registry-url` is intentionally omitted. When set, setup-node writes | |
| # `~/.npmrc` with `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}`. | |
| # Under Trusted Publisher (no `NPM_TOKEN` secret), the substitution | |
| # yields an empty `_authToken=` which npm treats as an unauthorized | |
| # request and returns 404 — bypassing OIDC exchange. Leaving the | |
| # registry URL as the built-in default lets npm CLI handle OIDC | |
| # trusted-publisher auth natively. | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '24' | |
| - name: Enable Corepack (post-setup-node) | |
| run: corepack enable | |
| - name: Pin Yarn version | |
| # Pins Yarn to the version that matches yarn.lock (lockfile version 8). | |
| # "yarn set version stable" upgrades to 4.14.x which introduced lockfile | |
| # format version 9, breaking --immutable installs. | |
| run: yarn set version 4.12.0 | |
| - name: Install | |
| run: yarn install --immutable | |
| - name: Build | |
| run: yarn build | |
| - name: Ensure Database Services | |
| run: docker compose up -d | |
| - name: Run Tests | |
| run: yarn test:all | |
| - name: Determine Version and Dist Tag | |
| id: version | |
| run: | | |
| set -euo pipefail | |
| STRATEGY=$(node -p "require('./lerna.json').version") | |
| if [ "$STRATEGY" = "independent" ]; then | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| CURRENT_VERSION=$(echo "$LATEST_TAG" | sed 's/^v//') | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" | |
| CURRENT_VERSION="v${MAJOR}.$((MINOR + 1)).0" | |
| DIST_TAG=$(node -p "require('./lerna.json').distTag || 'latest'") | |
| else | |
| CURRENT_VERSION=$(node -p "require('./lerna.json').version") | |
| if echo "$CURRENT_VERSION" | grep -q '-'; then | |
| DIST_TAG=$(echo "$CURRENT_VERSION" | cut -d '-' -f 2 | cut -d '.' -f 1) | |
| else | |
| DIST_TAG="latest" | |
| fi | |
| CURRENT_VERSION="v${CURRENT_VERSION}" | |
| fi | |
| echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" | |
| echo "dist_tag=$DIST_TAG" >> "$GITHUB_OUTPUT" | |
| - name: Check if Tag Exists | |
| id: check_tag | |
| run: | | |
| set -euo pipefail | |
| if [ -n "$(git tag -l "${{ steps.version.outputs.version }}")" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Resolve Release Notes Source | |
| id: notes | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| PR_NUMBER_INPUT: ${{ inputs.pr_number }} | |
| run: | | |
| set -euo pipefail | |
| if [ -n "${PR_NUMBER_INPUT:-}" ]; then | |
| BODY=$(gh pr view "$PR_NUMBER_INPUT" --json body --jq .body) | |
| PR_NUM="$PR_NUMBER_INPUT" | |
| else | |
| BODY="$PR_BODY" | |
| PR_NUM="${{ github.event.pull_request.number }}" | |
| fi | |
| { | |
| echo "body<<EOF_RELEASE_BODY" | |
| echo "$BODY" | |
| echo "EOF_RELEASE_BODY" | |
| } >> "$GITHUB_OUTPUT" | |
| echo "pr_number=$PR_NUM" >> "$GITHUB_OUTPUT" | |
| - name: Create Tag and Release | |
| if: steps.check_tag.outputs.exists == 'false' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_BODY: ${{ steps.notes.outputs.body }} | |
| run: | | |
| set -euo pipefail | |
| git tag "${{ steps.version.outputs.version }}" | |
| git push origin "${{ steps.version.outputs.version }}" | |
| gh release create "${{ steps.version.outputs.version }}" \ | |
| --title "${{ steps.version.outputs.version }}" \ | |
| --notes "$RELEASE_BODY" | |
| - name: Publish Packages to NPM Registry | |
| if: steps.check_tag.outputs.exists == 'false' | |
| env: | |
| NPM_CONFIG_PROVENANCE: true | |
| run: | | |
| set -euo pipefail | |
| # Per-package `npm publish` loop — bypasses lerna filtering because | |
| # lerna v9 removed both `--ignore` (renamed to `--ignore-changes` | |
| # with different semantics) and `--scope` for the publish command. | |
| # npm CLI v9.5+ handles OIDC trusted-publisher exchange transparently | |
| # when `id-token: write` permission + `environment: Release` are set | |
| # at the job level (both are already configured above). | |
| # | |
| DIST_TAG="${{ steps.version.outputs.dist_tag }}" | |
| PACKAGES=(core util request typeorm drizzle mikro-orm prisma) | |
| for pkg in "${PACKAGES[@]}"; do | |
| echo "::group::Publishing @nestjs-crud/$pkg@${{ steps.version.outputs.version }}" | |
| (cd "packages/$pkg" && npm publish --access public --tag "$DIST_TAG") | |
| echo "::endgroup::" | |
| done | |
| - name: Comment on Pull Request | |
| if: steps.check_tag.outputs.exists == 'false' && steps.notes.outputs.pr_number != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh pr comment ${{ steps.notes.outputs.pr_number }} \ | |
| --body "Packages with version [${{ steps.version.outputs.version }}](https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.version }}) have been released" |