Nx Cloud Workflow Release #41
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: Nx Cloud Workflow Release | |
| permissions: | |
| contents: read | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| commit: | |
| description: 'Commit SHA(s) to cherry-pick (comma-separated). All must be reachable from main.' | |
| required: false | |
| version: | |
| description: 'Version number for branch and tag (e.g. 6.0.1)' | |
| required: true | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| environment: release | |
| steps: | |
| - name: Generate app token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| app-id: ${{ secrets.RELEASE_APP_ID }} | |
| private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 | |
| with: | |
| fetch-depth: 0 | |
| filter: 'tree:0' | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Validate inputs | |
| env: | |
| VERSION_INPUT: ${{ github.event.inputs.version }} | |
| COMMIT_INPUT: ${{ github.event.inputs.commit }} | |
| run: | | |
| if ! [[ "$VERSION_INPUT" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then | |
| echo "Invalid version format: $VERSION_INPUT" >&2 | |
| echo "Version must be digits separated by dots (e.g. 6.0.1)." >&2 | |
| exit 1 | |
| fi | |
| if [ -n "$COMMIT_INPUT" ]; then | |
| IFS=',' read -ra COMMITS <<< "$COMMIT_INPUT" | |
| for sha in "${COMMITS[@]}"; do | |
| if ! [[ "$sha" =~ ^[a-f0-9]{7,40}$ ]]; then | |
| echo "Invalid commit SHA: $sha" >&2 | |
| exit 1 | |
| fi | |
| done | |
| fi | |
| - name: Configure git and fetch refs | |
| env: | |
| APP_SLUG: ${{ steps.app-token.outputs.app-slug }} | |
| run: | | |
| echo "# Nx Cloud Workflows Release" >> "$GITHUB_STEP_SUMMARY" | |
| git config user.name "${APP_SLUG}[bot]" | |
| git config user.email "${APP_SLUG}[bot]@users.noreply.github.com" | |
| git fetch origin main | |
| git fetch --tags origin | |
| - name: Verify commits are reachable from main | |
| if: ${{ github.event.inputs.commit }} | |
| env: | |
| COMMIT_INPUT: ${{ github.event.inputs.commit }} | |
| run: | | |
| IFS=',' read -ra COMMITS <<< "$COMMIT_INPUT" | |
| for sha in "${COMMITS[@]}"; do | |
| if ! git merge-base --is-ancestor "$sha" origin/main; then | |
| echo "Commit $sha is not reachable from origin/main." >&2 | |
| echo "Only commits merged to main (via PR review) can be released." >&2 | |
| exit 1 | |
| fi | |
| done | |
| - name: Create or checkout release branch | |
| env: | |
| VERSION_INPUT: ${{ github.event.inputs.version }} | |
| run: | | |
| MAJOR_VERSION="${VERSION_INPUT%%.*}" | |
| if git show-ref --verify --quiet "refs/remotes/origin/releases/v$MAJOR_VERSION"; then | |
| git checkout "releases/v$MAJOR_VERSION" | |
| else | |
| git checkout -b "releases/v$MAJOR_VERSION" | |
| fi | |
| - name: Cherry-pick commits | |
| if: ${{ github.event.inputs.commit }} | |
| env: | |
| COMMIT_INPUT: ${{ github.event.inputs.commit }} | |
| run: | | |
| IFS=',' read -ra COMMITS <<< "$COMMIT_INPUT" | |
| for sha in "${COMMITS[@]}"; do | |
| git cherry-pick "$sha" | |
| done | |
| - name: Push release branch | |
| env: | |
| VERSION_INPUT: ${{ github.event.inputs.version }} | |
| run: | | |
| MAJOR_VERSION="${VERSION_INPUT%%.*}" | |
| git push origin "releases/v$MAJOR_VERSION" | |
| echo "releases/v$MAJOR_VERSION updated" >> "$GITHUB_STEP_SUMMARY" | |
| - name: Create or update tags | |
| env: | |
| VERSION_INPUT: ${{ github.event.inputs.version }} | |
| run: | | |
| IFS='.' read -ra VERSIONS <<< "$VERSION_INPUT" | |
| TAG="" | |
| for segment in "${VERSIONS[@]}"; do | |
| if [ -z "$TAG" ]; then | |
| TAG="$segment" | |
| else | |
| TAG="$TAG.$segment" | |
| fi | |
| git tag -f "v$TAG" | |
| git push -f origin "v$TAG" | |
| echo "v$TAG created :rocket:" >> "$GITHUB_STEP_SUMMARY" | |
| done |