From 6d3bbce1fbae6c9a602970903ddc314986a874ec Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Tue, 23 Jun 2026 03:12:50 +0800 Subject: [PATCH 1/7] chore: add task to push changes from main to release/production --- .github/workflows/cd.yml | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f7c25c6..b84ed55 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -5,36 +5,26 @@ on: permissions: id-token: write - contents: read + contents: write actions: read security-events: write jobs: deploy: name: Build & Production Deploy - if: github.ref_name == 'production' + if: github.ref_name == 'main' runs-on: ubuntu-latest environment: production steps: - - name: Verify CI Workflow Completion - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "Checking the status of the latest 'CMS Continuous Integration' run for branch '${{ github.ref_name }}'..." - conclusion=$(gh run list --workflow "CMS Continuous Integration" --branch "${{ github.ref_name }}" --limit 1 --json conclusion --jq '.[0].conclusion') - - if [ -z "$conclusion" ]; then - echo "โŒ No runs found for the CI workflow on branch '${{ github.ref_name }}'." - exit 1 - elif [ "$conclusion" != "success" ]; then - echo "โŒ The latest run of the CI workflow on branch '${{ github.ref_name }}' is not successful (status: $conclusion)." - exit 1 - fi - - echo "โœ… The latest CI workflow run completed successfully." - - name: Checkout Source Code uses: actions/checkout@v4 + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + + - name: Push to Target Branch (release/production) + run: | + git checkout -B release/production + git push origin release/production --force-with-lease - name: Authenticate to AWS uses: aws-actions/configure-aws-credentials@v4 From bfc989e12b2d53812aeb09f7245df6536b9fd919 Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Tue, 23 Jun 2026 03:21:59 +0800 Subject: [PATCH 2/7] chore: optimize promotion to release --- .github/workflows/{cd.yml => deploy.yml} | 15 +++++---------- .github/workflows/promote.yml | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) rename .github/workflows/{cd.yml => deploy.yml} (93%) create mode 100644 .github/workflows/promote.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/deploy.yml similarity index 93% rename from .github/workflows/cd.yml rename to .github/workflows/deploy.yml index b84ed55..d4158a4 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/deploy.yml @@ -1,30 +1,25 @@ -name: CMS Continuous Delivery +name: CMS Production Continuous Delivery on: + push: + branches: + - release/production workflow_dispatch: permissions: id-token: write - contents: write + contents: read actions: read security-events: write jobs: deploy: name: Build & Production Deploy - if: github.ref_name == 'main' runs-on: ubuntu-latest environment: production steps: - name: Checkout Source Code uses: actions/checkout@v4 - with: - token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - - - name: Push to Target Branch (release/production) - run: | - git checkout -B release/production - git push origin release/production --force-with-lease - name: Authenticate to AWS uses: aws-actions/configure-aws-credentials@v4 diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml new file mode 100644 index 0000000..a1aed4a --- /dev/null +++ b/.github/workflows/promote.yml @@ -0,0 +1,23 @@ +name: CMS Promotion to Production + +on: + workflow_dispatch: + +permissions: + contents: write + +jobs: + promote: + name: Promote Main to Release + if: github.ref_name == 'main' + runs-on: ubuntu-latest + steps: + - name: Checkout Source Code + uses: actions/checkout@v4 + with: + token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} + + - name: Push to Target Branch (release/production) + run: | + git checkout -B release/production + git push origin release/production --force-with-lease From 02df162a83a290e482382f77bd7ae79dda90ebb5 Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Tue, 23 Jun 2026 03:28:33 +0800 Subject: [PATCH 3/7] chore(promote.yml): change force with lease to just force --- .github/workflows/promote.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml index a1aed4a..28a80f0 100644 --- a/.github/workflows/promote.yml +++ b/.github/workflows/promote.yml @@ -20,4 +20,4 @@ jobs: - name: Push to Target Branch (release/production) run: | git checkout -B release/production - git push origin release/production --force-with-lease + git push origin release/production --force From af683de05ea28c9e7531135ba27fbc84223c45e1 Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Tue, 23 Jun 2026 03:47:22 +0800 Subject: [PATCH 4/7] chore: add auto pr task for promotion pipeline --- .github/workflows/promote.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml index 28a80f0..8183d94 100644 --- a/.github/workflows/promote.yml +++ b/.github/workflows/promote.yml @@ -5,6 +5,7 @@ on: permissions: contents: write + pull-requests: write jobs: promote: @@ -17,7 +18,14 @@ jobs: with: token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - - name: Push to Target Branch (release/production) + - name: Create Auto PR and Merge + env: + GH_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} run: | - git checkout -B release/production - git push origin release/production --force + pr_url=$(gh pr create \ + --title "Release: Promote main to production" \ + --body "Automated promotion from main branch" \ + --base release/production \ + --head main || gh pr list --base release/production --head main --json url --jq '.[0].url') + + gh pr merge "$pr_url" --rebase --admin --auto From 83a214e07328566fd5c986a62306b6397346f638 Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Sun, 12 Jul 2026 01:28:01 +0800 Subject: [PATCH 5/7] ci: add git tagging and pr to release/production workflow --- .../pull_request_template.md | 55 ++++++++++++++++++ .../release_production.md | 31 ++++++++++ .github/pull_request_template.md | 57 +------------------ .github/release.yml | 41 +++++++++++++ .github/workflows/{deploy.yml => cd.yml} | 52 ++++++++++------- .github/workflows/ci.yml | 26 +++++++++ .github/workflows/promote.yml | 31 ---------- scripts/bump-version.sh | 46 +++++++++++++++ 8 files changed, 233 insertions(+), 106 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/release_production.md mode change 100644 => 120000 .github/pull_request_template.md create mode 100644 .github/release.yml rename .github/workflows/{deploy.yml => cd.yml} (78%) delete mode 100644 .github/workflows/promote.yml create mode 100755 scripts/bump-version.sh diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..19f21ce --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,55 @@ +## ๐Ÿ“ Overview + +_What does this PR do? Briefly describe the changes and the goal of this PR._ + +## ๐Ÿš€ Type of Change + +- [ ] ๐Ÿ› **Bug Fix**: Fixed something that was broken. +- [ ] โœจ **New Feature**: Added new functionality or pages. +- [ ] ๐Ÿ—„๏ธ **CMS / Database**: Updated collections, fields, or config in Payload CMS. +- [ ] ๐Ÿงน **Chore / Clean up**: Text updates, typos, or code cleanup. + +--- + +## ๐Ÿงฑ CMS & Database Changes + +_Skip this section if no CMS or database changes were made._ + +- [ ] **Migration Created**: Ran `payload migrate:create` and saved the file. +- [ ] **Local Verification**: Verified changes in the local admin panel. + +### ๐Ÿ“Š Data Structure + +_Describe the new fields/tables or drag-and-drop a screenshot here:_ + +--- + +## ๐Ÿงช Testing & Validation + +- [ ] **Test Case Approval**: Verified that test cases were commented on the assigned GitHub issue and approved by the Project Lead _before_ development started. +- [ ] **Unit Tests**: Added or updated unit test scripts covering the new logic. +- [ ] **Admin Panel**: Verified behavior in the CMS Admin UI. +- [ ] **API Check**: Tested REST/GraphQL endpoints for correct data. + +### ๐Ÿ“ธ Visual Evidence (Mandatory) + +> [!IMPORTANT] +> Visual proof is required to demonstrate that the approved test cases from the issue were successfully met. +> Please provide screenshots, screen recordings (GIFs/Videos), or sample API outputs proving that the feature satisfies all approved test cases and do not introduce regressions. + +--- + +## ๐Ÿ“‹ Final Checklist + +- [ ] **Sync**: Rebased from `main` and resolved conflicts. +- [ ] **Pre-commit**: Installed and ran pre-commit hooks successfully. +- [ ] **Security**: Verified no secrets or local credentials are included. +- [ ] **Build**: Project builds without errors. +- [ ] **Visuals**: Attached mandatory visual evidence proving all test cases passed. +- [ ] **Migrations**: Migration script included (if applicable). + +--- + +## ๐Ÿง  Extra Notes / Questions + +_Add any additional context or questions for the reviewers here._ diff --git a/.github/PULL_REQUEST_TEMPLATE/release_production.md b/.github/PULL_REQUEST_TEMPLATE/release_production.md new file mode 100644 index 0000000..aceb4ca --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/release_production.md @@ -0,0 +1,31 @@ +## ๐Ÿš€ Production Release PR + +> [!IMPORTANT] > **Action Required**: You MUST apply one of the following labels to this PR in the GitHub sidebar before merging: +> +> - `release:major` (Breaking changes โ€” e.g., `1.0.0` โžก๏ธ `2.0.0`) +> - `release:minor` (New features / non-breaking schema additions โ€” e.g., `1.0.0` โžก๏ธ `1.1.0`) +> - `release:patch` (Bug fixes / chores โ€” e.g., `1.0.0` โžก๏ธ `1.0.1`) +> +> This label is required by the CD workflow to calculate the version bump and publish the release. + +--- + +## ๐Ÿ“ Release Summary + +_Briefly summarize the major changes included in this release._ + +## ๐Ÿ“Š Included Changes (from main) + +_List the features or fixes being promoted, or link to the PRs/Issues._ + +- [ ] Feature/Fix 1 (#PR-number) +- [ ] Feature/Fix 2 (#PR-number) + +--- + +## ๐Ÿ“‹ Release Checklist + +- [ ] **CI Validation**: Verify that the CI checks have passed on `main`. +- [ ] **PR Labels**: Applied the appropriate `release:major`, `release:minor`, or `release:patch` label to this PR. +- [ ] **Database Migrations**: Verified that any database migration scripts are tested and ready for production. +- [ ] **QA Approval**: Changes have been tested and verified in staging/dev environment. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 850b6ff..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,56 +0,0 @@ -## ๐Ÿ“ Overview - -_What does this PR do? Briefly describe the changes and the goal of this PR._ - -## ๐Ÿš€ Type of Change - -- [ ] ๐Ÿ› **Bug Fix**: Fixed something that was broken. -- [ ] โœจ **New Feature**: Added new functionality or pages. -- [ ] ๐Ÿ—„๏ธ **CMS / Database**: Updated collections, fields, or config in Payload CMS. -- [ ] ๐Ÿงน **Chore / Clean up**: Text updates, typos, or code cleanup. - ---- - -## ๐Ÿงฑ CMS & Database Changes - -_Skip this section if no CMS or database changes were made._ - -- [ ] **Migration Created**: Ran `payload migrate:create` and saved the file. -- [ ] **Local Verification**: Verified changes in the local admin panel. - -### ๐Ÿ“Š Data Structure - -_Describe the new fields/tables or drag-and-drop a screenshot here:_ - ---- - -## ๐Ÿงช Testing & Validation - -- [ ] **Test Case Approval**: Verified that test cases were commented on the assigned GitHub issue and approved by the Project Lead _before_ development started. -- [ ] **Unit Tests**: Added or updated unit test scripts covering the new logic. -- [ ] **Admin Panel**: Verified behavior in the CMS Admin UI. -- [ ] **API Check**: Tested REST/GraphQL endpoints for correct data. - -### ๐Ÿ“ธ Visual Evidence (Mandatory) - -> [!IMPORTANT] -> Visual proof is required to demonstrate that the approved test cases from the issue were successfully met. - -_Please provide screenshots, screen recordings (GIFs/Videos), or sample API outputs proving that the feature satisfies all approved test cases and do not introduce regressions._ - ---- - -## ๐Ÿ“‹ Final Checklist - -- [ ] **Sync**: Rebased from `main` and resolved conflicts. -- [ ] **Pre-commit**: Installed and ran pre-commit hooks successfully. -- [ ] **Security**: Verified no secrets or local credentials are included. -- [ ] **Build**: Project builds without errors. -- [ ] **Visuals**: Attached mandatory visual evidence proving all test cases passed. -- [ ] **Migrations**: Migration script included (if applicable). - ---- - -## ๐Ÿง  Extra Notes / Questions - -_Add any additional context or questions for the reviewers here._ diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 120000 index 0000000..83e9af9 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1 @@ +PULL_REQUEST_TEMPLATE/pull_request_template.md \ No newline at end of file diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..2ec4f71 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,41 @@ +changelog: + exclude: + labels: + - ignore-release + - duplicate + authors: + - github-actions[bot] + - dependabot[bot] + + categories: + - title: '๐Ÿš€ Features' + labels: + - feature + - feat + - enhancement + + - title: '๐Ÿ› Bug Fixes' + labels: + - bug + - fix + - hotfix + + - title: '๐Ÿ“– Documentation' + labels: + - documentation + - docs + + - title: 'โš™๏ธ Refactoring & Infrastructure' + labels: + - refactor + - chore + - ci + + - title: '๐Ÿ“ฆ Dependency Updates' + labels: + - dependencies + - dependency + + - title: '๐Ÿก Other Changes' + labels: + - '*' diff --git a/.github/workflows/deploy.yml b/.github/workflows/cd.yml similarity index 78% rename from .github/workflows/deploy.yml rename to .github/workflows/cd.yml index d4158a4..07ead6a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/cd.yml @@ -8,9 +8,9 @@ on: permissions: id-token: write - contents: read + contents: write actions: read - security-events: write + pull-requests: read jobs: deploy: @@ -20,6 +20,8 @@ jobs: steps: - name: Checkout Source Code uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Authenticate to AWS uses: aws-actions/configure-aws-credentials@v4 @@ -47,6 +49,12 @@ jobs: mask-values: true recursive: true + - name: Determine and Apply Version Bump + id: version-bump + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: ./scripts/bump-version.sh + - name: Install Dependencies run: npm ci --legacy-peer-deps @@ -98,22 +106,6 @@ jobs: AWS_DEFAULT_REGION=ap-southeast-1 ENVIRONMENT=production - - name: Codebase Scan (Vulnerabilities & Misconfigurations) - uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0 - with: - scan-type: 'fs' - scan-ref: '.' - scanners: 'vuln,misconfig' - format: 'sarif' - output: 'trivy-results.sarif' - severity: 'CRITICAL,HIGH' - skip-files: '.env.ci-build' - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: 'trivy-results.sarif' - - name: Push Image if: success() run: | @@ -124,7 +116,6 @@ jobs: run: | echo "### ๐Ÿšข Deployment Summary" >> $GITHUB_STEP_SUMMARY echo "Image: \`${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY - echo "Security Scan: Results uploaded to the GitHub Security tab." >> $GITHUB_STEP_SUMMARY - name: Deploy to AWS Lambda if: success() @@ -132,3 +123,26 @@ jobs: aws lambda update-function-code \ --function-name durianpy-cms-prod \ --image-uri ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} + + - name: Commit and Push Version Bump + if: success() + env: + NEW_TAG: ${{ steps.version-bump.outputs.new_tag }} + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add package.json + git commit -m "chore(release): bump version to $NEW_TAG [skip ci]" + git push origin release/production + + - name: Create Git Tag and Release + if: success() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEW_TAG: ${{ steps.version-bump.outputs.new_tag }} + run: | + echo "๐Ÿš€ Creating GitHub Release for $NEW_TAG..." + gh release create "$NEW_TAG" \ + --title "Release $NEW_TAG" \ + --generate-notes \ + --target "release/production" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2b274f..f8479c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,13 +4,39 @@ on: pull_request: branches: - main + - release/production permissions: id-token: write contents: read security-events: write + pull-requests: read jobs: + check-labels: + name: Verify Release Labels + if: github.base_ref == 'release/production' + runs-on: ubuntu-latest + steps: + - name: Check PR Labels + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + LABELS=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name') + echo "PR Labels: $LABELS" + + if echo "$LABELS" | grep -q "release:major"; then + echo "โœ… Found release:major label." + elif echo "$LABELS" | grep -q "release:minor"; then + echo "โœ… Found release:minor label." + elif echo "$LABELS" | grep -q "release:patch"; then + echo "โœ… Found release:patch label." + else + echo "โŒ Error: Pull Requests targeting release/production must have one of these labels: release:major, release:minor, or release:patch" + exit 1 + fi + validate: name: Validation & Security runs-on: ubuntu-latest diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml deleted file mode 100644 index 8183d94..0000000 --- a/.github/workflows/promote.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: CMS Promotion to Production - -on: - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -jobs: - promote: - name: Promote Main to Release - if: github.ref_name == 'main' - runs-on: ubuntu-latest - steps: - - name: Checkout Source Code - uses: actions/checkout@v4 - with: - token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - - - name: Create Auto PR and Merge - env: - GH_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }} - run: | - pr_url=$(gh pr create \ - --title "Release: Promote main to production" \ - --body "Automated promotion from main branch" \ - --base release/production \ - --head main || gh pr list --base release/production --head main --json url --jq '.[0].url') - - gh pr merge "$pr_url" --rebase --admin --auto diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh new file mode 100755 index 0000000..dc96e88 --- /dev/null +++ b/scripts/bump-version.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e + +# 1. Fetch the merged PR associated with this commit +PR_JSON=$(gh api repos/"$GITHUB_REPOSITORY"/commits/"$GITHUB_SHA"/pulls 2>/dev/null || echo "[]") +LABELS=$(echo "$PR_JSON" | jq -r '.[0].labels[].name' 2>/dev/null || echo "") + +# 2. Determine bump type +BUMP_TYPE="" +if echo "$LABELS" | grep -q "release:major"; then + BUMP_TYPE="major" +elif echo "$LABELS" | grep -q "release:minor"; then + BUMP_TYPE="minor" +elif echo "$LABELS" | grep -q "release:patch"; then + BUMP_TYPE="patch" +else + echo "โš ๏ธ No release labels found on the merged PR. Defaulting to patch bump." + BUMP_TYPE="patch" +fi + +echo "Selected bump type: $BUMP_TYPE" + +# 3. Find the latest released Git tag to base the bump on +git fetch --tags +LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") +echo "Latest release tag: $LATEST_TAG" + +# Clean tag version (remove 'v' prefix) +PREV_VERSION="${LATEST_TAG#v}" + +# Set package.json version to the latest tag version temporarily +node -e " + const pkg = require('./package.json'); + pkg.version = '$PREV_VERSION'; + require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n'); +" + +# 4. Bump version using npm +NEW_VERSION=$(npm version "$BUMP_TYPE" --no-git-tag-version) +TAG_NAME="$NEW_VERSION" +echo "New Version: $TAG_NAME" + +# Expose new tag for subsequent steps in GitHub Actions +if [ -n "$GITHUB_OUTPUT" ]; then + echo "new_tag=$TAG_NAME" >> "$GITHUB_OUTPUT" +fi From 48e089b60753215734a23358be467d2e8a5cdac5 Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Sun, 12 Jul 2026 01:43:09 +0800 Subject: [PATCH 6/7] ci(cd): tag ECR images and Lambda deployments with SemVer release version --- .github/workflows/cd.yml | 10 +++++----- .github/workflows/ci.yml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 07ead6a..3384369 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,4 +1,4 @@ -name: CMS Production Continuous Delivery +name: Production CD Pipeline on: push: @@ -94,7 +94,7 @@ jobs: file: docker/lambda/Dockerfile load: true tags: | - ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} + ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ steps.version-bump.outputs.new_tag }} secrets: | payload_secret=${{ steps.ssm-param.outputs.PAYLOAD_SECRET }} database_url=${{ steps.ssm-param.outputs.DATABASE_URL }} @@ -109,20 +109,20 @@ jobs: - name: Push Image if: success() run: | - docker push ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} + docker push ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ steps.version-bump.outputs.new_tag }} - name: Summarize Build if: always() run: | echo "### ๐Ÿšข Deployment Summary" >> $GITHUB_STEP_SUMMARY - echo "Image: \`${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY + echo "Image: \`${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ steps.version-bump.outputs.new_tag }}\`" >> $GITHUB_STEP_SUMMARY - name: Deploy to AWS Lambda if: success() run: | aws lambda update-function-code \ --function-name durianpy-cms-prod \ - --image-uri ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ github.sha }} + --image-uri ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ steps.version-bump.outputs.new_tag }} - name: Commit and Push Version Bump if: success() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8479c3..53673b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CMS Continuous Integration +name: CI Pipeline on: pull_request: From 71ed54998275d6a43eebea9f5edf2341c4aed6cb Mon Sep 17 00:00:00 2001 From: Anakin Skywalker Pactores Date: Sun, 12 Jul 2026 02:25:39 +0800 Subject: [PATCH 7/7] ci: enforce release labels, add manual bump inputs, and automate changelog --- .github/workflows/cd.yml | 31 ++++++++++++++++++++++++++++--- .github/workflows/ci.yml | 26 -------------------------- scripts/bump-version.sh | 21 +++++++++++++-------- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 3384369..544b9a0 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -5,6 +5,16 @@ on: branches: - release/production workflow_dispatch: + inputs: + bump_type: + description: 'SemVer bump type (used if manual run)' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major permissions: id-token: write @@ -53,6 +63,7 @@ jobs: id: version-bump env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BUMP_TYPE_INPUT: ${{ github.event.inputs.bump_type }} run: ./scripts/bump-version.sh - name: Install Dependencies @@ -124,15 +135,29 @@ jobs: --function-name durianpy-cms-prod \ --image-uri ${{ steps.login-ecr.outputs.registry }}/durianpy-cms-prod:${{ steps.version-bump.outputs.new_tag }} - - name: Commit and Push Version Bump + - name: Commit and Push Version Bump and CHANGELOG if: success() env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NEW_TAG: ${{ steps.version-bump.outputs.new_tag }} run: | + # 1. Generate release notes from GitHub API + echo "Generating release notes for $NEW_TAG..." + RELEASE_NOTES=$(gh release generate-notes --tag "$NEW_TAG" --target "release/production") + + # 2. Prepend notes to CHANGELOG.md + DATE_STR=$(date +%Y-%m-%d) + if [ -f CHANGELOG.md ]; then + echo -e "# Release $NEW_TAG ($DATE_STR)\n\n$RELEASE_NOTES\n\n$(cat CHANGELOG.md)" > CHANGELOG.md + else + echo -e "# Release $NEW_TAG ($DATE_STR)\n\n$RELEASE_NOTES" > CHANGELOG.md + fi + + # 3. Commit and push changes git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add package.json - git commit -m "chore(release): bump version to $NEW_TAG [skip ci]" + git add package.json CHANGELOG.md + git commit -m "chore(release): bump version to $NEW_TAG and update CHANGELOG [skip ci]" git push origin release/production - name: Create Git Tag and Release diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53673b8..e2e5d7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,39 +4,13 @@ on: pull_request: branches: - main - - release/production permissions: id-token: write contents: read security-events: write - pull-requests: read jobs: - check-labels: - name: Verify Release Labels - if: github.base_ref == 'release/production' - runs-on: ubuntu-latest - steps: - - name: Check PR Labels - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - LABELS=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name') - echo "PR Labels: $LABELS" - - if echo "$LABELS" | grep -q "release:major"; then - echo "โœ… Found release:major label." - elif echo "$LABELS" | grep -q "release:minor"; then - echo "โœ… Found release:minor label." - elif echo "$LABELS" | grep -q "release:patch"; then - echo "โœ… Found release:patch label." - else - echo "โŒ Error: Pull Requests targeting release/production must have one of these labels: release:major, release:minor, or release:patch" - exit 1 - fi - validate: name: Validation & Security runs-on: ubuntu-latest diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index dc96e88..03b024b 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -7,15 +7,20 @@ LABELS=$(echo "$PR_JSON" | jq -r '.[0].labels[].name' 2>/dev/null || echo "") # 2. Determine bump type BUMP_TYPE="" -if echo "$LABELS" | grep -q "release:major"; then - BUMP_TYPE="major" -elif echo "$LABELS" | grep -q "release:minor"; then - BUMP_TYPE="minor" -elif echo "$LABELS" | grep -q "release:patch"; then - BUMP_TYPE="patch" +if [ -n "$BUMP_TYPE_INPUT" ]; then + BUMP_TYPE="$BUMP_TYPE_INPUT" + echo "Manual run input detected. Selected bump type: $BUMP_TYPE" else - echo "โš ๏ธ No release labels found on the merged PR. Defaulting to patch bump." - BUMP_TYPE="patch" + if echo "$LABELS" | grep -q "release:major"; then + BUMP_TYPE="major" + elif echo "$LABELS" | grep -q "release:minor"; then + BUMP_TYPE="minor" + elif echo "$LABELS" | grep -q "release:patch"; then + BUMP_TYPE="patch" + else + echo "โŒ Error: Pull Requests targeting release/production must have one of these labels: release:major, release:minor, or release:patch" + exit 1 + fi fi echo "Selected bump type: $BUMP_TYPE"