diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1635f2f0f..90b7de4f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,45 @@ jobs: - run: pnpm exec playwright install - - uses: nrwl/nx-set-shas@v4 + - name: Get base and head SHAs for Nx affected commands + id: get-shas + run: | + set -e # Exit immediately if a command exits with a non-zero status + + # Check if 'gh' command is available + if ! command -v gh &> /dev/null; then + echo "Error: GitHub CLI (gh) is not installed." >&2 + exit 1 + fi + + # Get latest release tag + echo "Fetching latest GitHub release..." + LATEST_RELEASE_TAG=$(gh release view --json tagName -q .tagName) + + if [ -z "$LATEST_RELEASE_TAG" ]; then + exit 1 + else + echo "Latest release tag: $LATEST_RELEASE_TAG" + # Get the commit SHA that this tag points to + BASE_SHA=$(git rev-list -n 1 $LATEST_RELEASE_TAG) + fi + + # Get current HEAD SHA + HEAD_SHA=$(git rev-parse HEAD) + + echo "Base SHA (latest release): $BASE_SHA" + echo "Head SHA (current): $HEAD_SHA" + + # Set outputs for use with Nx + echo "base_sha=$BASE_SHA" >> $GITHUB_OUTPUT + echo "head_sha=$HEAD_SHA" >> $GITHUB_OUTPUT + + # Export as environment variables for immediate use + echo "NX_BASE=$BASE_SHA" >> $GITHUB_ENV + echo "NX_HEAD=$HEAD_SHA" >> $GITHUB_ENV + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # This line is needed for nx affected to work when CI is running on a PR - run: git branch --track main origin/main @@ -68,13 +106,8 @@ jobs: - name: build docs run: pnpm generate-docs - - name: preview-docs - uses: rajyan/preview-pages@v1 - with: - source-dir: docs - pr-comment: 'none' - - - name: Update comment - uses: marocchino/sticky-pull-request-comment@v2 + - name: Publish api docs + uses: JamesIves/github-pages-deploy-action@v4.7.3 with: - message: Deployed ${{ github.sha }} to https://ForgeRock.github.io/ping-javascript-sdk/pr-${{ github.event.number }}/${{github.sha}} branch gh-pages in ForgeRock/ping-javascript-sdk + folder: docs + commit-message: 'chore: release-api-docs' diff --git a/.github/workflows/patch-release.yml b/.github/workflows/patch-release.yml new file mode 100644 index 000000000..d1509fa4f --- /dev/null +++ b/.github/workflows/patch-release.yml @@ -0,0 +1,91 @@ +name: Release Patch +on: + workflow_dispatch: + inputs: + branch-name: + description: 'Name for the patch branch (typically like "patch-release-1.0.1")' + required: true + +env: + NX_CLOUD_ENCRYPTION_KEY: ${{ secrets.NX_CLOUD_ENCRYPTION_KEY }} + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + NX_CLOUD_DISTRIBUTED_EXECUTION: true + PNPM_CACHE_FOLDER: .pnpm-store + NPM_ACCESS_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CI: true + +jobs: + create-and-publish-patch: + permissions: + contents: write # to create release (changesets/action) + issues: write # to post issue comments (changesets/action) + pull-requests: write # to create pull request (changesets/action) + id-token: write # give id token write for provenance + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GH_TOKEN }} + + # Check out the provided branch - fail if it doesn't exist + - name: Checkout patch branch + run: | + git checkout ${{ github.event.inputs.branch-name }} + + # Setup environment + - uses: pnpm/action-setup@v4 + with: + run_install: false + - uses: actions/setup-node@v4 + with: + node-version: '22.14.0' + cache: 'pnpm' + + - run: pnpm install --frozen-lockfile + + # This line enables distribution for NX + - run: pnpm dlx nx-cloud start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yml" --stop-agents-after="e2e-ci" --with-env-vars="CODECOV_TOKEN" + + - run: pnpm exec playwright install + + - uses: nrwl/nx-set-shas@v4 + + - name: Setup pnpm config + run: pnpm config set store-dir $PNPM_CACHE_FOLDER + + - name: Version packages + run: pnpm exec changeset version + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + + # Build and test affected packages + - name: Build and test + run: pnpm exec nx affected -t build lint test e2e-ci + + - name: Publish patch + run: | + echo "//registry.npmjs.org/:_authToken=$NPM_ACCESS_TOKEN" > .npmrc + pnpm publish -r + env: + NPM_CONFIG_PROVENANCE: 'true' + NPM_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} + + # Use changeset tag to create git tags according to changesets config + - name: Create and push git tags + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Actions" + pnpm exec changeset tag + git push --follow-tags + + # Build and publish docs for the patch + - name: Build docs + run: pnpm generate-docs + + - name: Publish api docs + uses: JamesIves/github-pages-deploy-action@v4.7.3 + with: + folder: docs + commit-message: 'chore: release-api-docs-patch' diff --git a/contributing_docs/releases.md b/contributing_docs/releases.md index 279d3b8ba..0f3e2beb4 100644 --- a/contributing_docs/releases.md +++ b/contributing_docs/releases.md @@ -95,3 +95,54 @@ We provide verdaccio two ways: topological graph. - Publishing to a hosted private registry: Please message @ryanbas21 on slack. + +# Patch Releases + +In the event a patch release is required, we should always fix the bug on `main` before releasing any code. + +This follows the trunk based development style of releasing which is best suited for changesets. + +Once the bug is confirmed fixed, we can cherry-pick the fix from main, onto the latest release branch. + +This cherry-pick should contain a changeset, if it does not, we will need to add one. + +Once we have that new release branch confirmed working, and it has a changeset, we can push the branch to github. + +We can then use the workflow_dispatch github workflow, called patch-release.yml, pass in the branch to release from as an input. + +This will kickoff the release workflow, including building, testing, linting, etc. + +Once passing, we will attempt to publish with provenance from CI (signing the packages). + +It is worth noting that we could be on 1.0.1 on `npm` and our `main` branch may be on versions `1.0.0`. But because we push the tag up, changesets should respect the tag, and versions should be triggered based on the tag in the Release PR + +## Patch Release Process + +- Identify and fix the bug on main first + This allows us to properly reproduce and verify the fix + It ensures proper code review through your normal PR process + The fix gets merged to main and will be included in future releases + +- After the fix is merged to main, cherry-pick it to a patch branch + +- Create a branch from the last release tag (e.g., v1.0.0) + +- Cherry-pick the bugfix commit(s) from main to this patch branch + +- Add a changeset file describing the patch change + +- Push the patch branch and run the patch workflow + +- This will publish the patch version (e.g., 1.0.1) + +- No need to merge back to main + + Since the fix already exists on main, there's no need to merge back + This prevents any potential merge conflicts or duplication + +This approach provides several benefits: + +- Ensures the bug is properly identified and fixed first +- Maintains normal code review process +- Creates a clean git history with the fix clearly flowing from main to the patch branch +- Avoids duplication of changes or complicated merge operations