From 3147c093588cee72c3d3082c1460a2af20458d29 Mon Sep 17 00:00:00 2001 From: Calvin Cheng Date: Fri, 11 Sep 2026 21:47:48 +0000 Subject: [PATCH 1/4] ci(release): automate release management and enforce conventional commit PR titles --- .github/labeler.yml | 23 ++++++++++++++++++++ .github/workflows/labeler.yml | 23 ++++++++++++++++++++ .github/workflows/release.yml | 29 +++++++++++++++++++++++++ .github/workflows/semantic-pr.yml | 36 +++++++++++++++++++++++++++++++ .release-please-manifest.json | 3 +++ release-please-config.json | 24 +++++++++++++++++++++ 6 files changed, 138 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/labeler.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/semantic-pr.yml create mode 100644 .release-please-manifest.json create mode 100644 release-please-config.json diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..4252f731a --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,23 @@ +"modules": + - changed-files: + - any-glob-to-any-file: 'modules/**' + +"fast": + - changed-files: + - any-glob-to-any-file: 'fast/**' + +"blueprints: fedramp-high": + - changed-files: + - any-glob-to-any-file: 'blueprints/fedramp-high/**' + +"blueprints: il5": + - changed-files: + - any-glob-to-any-file: 'blueprints/il5/**' + +"blueprints: stand-alone": + - changed-files: + - any-glob-to-any-file: 'blueprints/stand-alone/**' + +"blueprints: third-party-solutions": + - changed-files: + - any-glob-to-any-file: 'blueprints/third-party-solutions/**' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..95feac235 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,23 @@ +name: "Pull Request Labeler" + +on: + pull_request: + types: + - opened + - synchronize + - reopened + +permissions: + contents: read + pull-requests: write + +jobs: + label: + name: Run Labeler + runs-on: ubuntu-latest + steps: + - name: Apply PR Labels + uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 + with: + configuration-path: .github/labeler.yml + sync-labels: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..48cf50f2e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: "Auto Release" + +on: + push: + branches: + - test-release-automation + +permissions: + contents: write + pull-requests: write + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - name: Generate Release + id: release + uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 + with: + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + target-branch: test-release-automation + + - name: On Release Created + if: ${{ steps.release.outputs.release_created }} + env: + TAG_NAME: ${{ steps.release.outputs.tag_name }} + run: | + echo "Successfully published release: $TAG_NAME" diff --git a/.github/workflows/semantic-pr.yml b/.github/workflows/semantic-pr.yml new file mode 100644 index 000000000..fb7e52422 --- /dev/null +++ b/.github/workflows/semantic-pr.yml @@ -0,0 +1,36 @@ +name: "Lint Pull Request" + +on: + pull_request: + types: + - opened + - edited + - synchronize + - reopened + +permissions: + pull-requests: read + +jobs: + validate-title: + name: Validate PR Title + runs-on: ubuntu-latest + steps: + - name: Check PR Title format + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + echo "Validating PR Title: $PR_TITLE" + + # Regex matches Conventional Commits format (e.g., modules(kms): add cloud HSM protection support) + PATTERN="^(feat|fix|chore|docs|ci|test|refactor|style|modules|fast|blueprints)(\([a-zA-Z0-9_/_-]+\))?!?: .+$" + + if [[ ! "$PR_TITLE" =~ $PATTERN ]]; then + echo "::error::PR Title does not match the Conventional Commits specification!" + echo "Expected format: (): or : " + echo "Allowed types: feat, fix, chore, docs, ci, test, refactor, style, modules, fast, blueprints" + echo "Example: modules(kms): add HSM protection support" + exit 1 + fi + + echo "PR Title matches Conventional Commits format successfully!" diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 000000000..e6f877563 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "4.0.0" +} diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 000000000..0e13244aa --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,24 @@ +{ + "packages": { + ".": { + "release-type": "simple", + "pr-title-pattern": "release: v${version}", + "changelog-path": "CHANGELOG.md", + "changelog-sections": [ + {"type": "modules", "section": "Modules", "hidden": false}, + {"type": "fast", "section": "FAST Stages", "hidden": false}, + {"type": "blueprints", "section": "Blueprints", "hidden": false}, + {"type": "feat", "section": "Features", "hidden": false}, + {"type": "fix", "section": "Bug Fixes", "hidden": false}, + {"type": "security", "section": "Security Updates", "hidden": false}, + {"type": "refactor", "section": "Refactors", "hidden": false}, + {"type": "ci", "section": "CI/CD Workflows", "hidden": true}, + {"type": "test", "section": "Tests", "hidden": true}, + {"type": "style", "section": "Style Updates", "hidden": true}, + {"type": "chore", "section": "Housekeeping", "hidden": true}, + {"type": "docs", "section": "Documentation", "hidden": true} + ] + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} From f8a7cc7be073c2ae8455b9406682c4b34a5bf9aa Mon Sep 17 00:00:00 2001 From: Calvin Cheng Date: Fri, 11 Sep 2026 21:47:50 +0000 Subject: [PATCH 2/4] docs: update release strategy and guidelines for conventional commits --- releases.md | 66 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/releases.md b/releases.md index b79a6d42d..99f8d3d7b 100644 --- a/releases.md +++ b/releases.md @@ -4,49 +4,71 @@ This document outlines the versioning scheme, release classification, and releas ## Release Classification and Versioning Scheme -`stellar-engine` follows Semantic Versioning (`vMAJOR.MINOR.PATCH`). Releases are categorized based on their impact on underlying Terraform state and deployed infrastructure resources. +`stellar-engine` follows Semantic Versioning (`vMAJOR.MINOR.PATCH`). To maintain complete transparency and predictability for our users, releases are automated and categorized based on the syntax of merged commit messages. ### Major Releases Major releases (e.g., `vX.0.0`) cover breaking changes or updates that require state manipulation or resource redeployment. -* Definition: Any changes that require: +* **Definition:** Any changes that require: * Terraform state manipulation (e.g., manual state modification, removals). * Terraform state moves (`terraform state mv` or refactoring existing resource addresses). * Redeployment or recreation of existing infrastructure resources. -* Process: Executed manually. -* Upgrade Guidance: Major releases will include detailed migration notes, state refactoring scripts, or step-by-step instructions for upgrading existing environments without unexpected downtime or state drift. +* **Trigger:** Initiated by including a `BREAKING CHANGE:` in the commit body, or by suffixing the commit type with `!` (e.g., `feat(kms)!: remove old KMS key configuration`). +* **Upgrade Guidance:** Major releases will include detailed migration notes, state refactoring scripts, or step-by-step instructions for upgrading existing environments without unexpected downtime or state drift. ### Minor Releases Minor releases (e.g., `vX.Y.0`) cover backwards-compatible feature additions, updates, and enhancements. -* Definition: Feature additions, enhancements, or updates that do not require Terraform state manipulation, state moves, or redeployment of existing resources (e.g., backwards-compatible infrastructure additions, non-destructive parameter updates). -* Process: Generated monthly on the last Friday of the month automatically from the `main` branch. +* **Definition:** Feature additions, enhancements, or updates that do not require Terraform state manipulation, state moves, or redeployment of existing resources (e.g., backwards-compatible infrastructure additions, non-destructive parameter updates). +* **Trigger:** Initiated by a commit prefixed with `feat:` (e.g., `feat(bigquery): add support for partitioning`). ### Patch Releases Patch releases (e.g., `vX.Y.Z`) cover critical bug fixes, security patches, and urgent non-breaking adjustments. -* Definition: Critical bug fixes, security patches, or urgent non-breaking adjustments. -* Process: Executed on an ad-hoc basis, where the release is updated and tagged manually. +* **Definition:** Critical bug fixes, security patches, or urgent non-breaking adjustments. +* **Trigger:** Initiated by a commit prefixed with `fix:` (e.g., `fix(gcs): resolve bucket logging variable type`). + +--- ## Release Cadence and Automation Summary -| Release Type | Trigger / Cadence | Execution | State Manipulation / Redeploy Required? | -| :--- | :--- | :--- | :--- | -| Major (`vX.0.0`) | As needed | Manual | Yes | -| Minor (`vX.Y.0`) | Monthly | Automated (from `main`) | No | -| Patch (`vX.Y.Z`) | Ad-hoc / As needed | Manual | No | +The repository uses Google's **Release Please** to automate release preparation. Release Please continuously compiles a draft release in an open **Release Pull Request** as changes are merged to the `main` branch. The actual release is published when a maintainer merges this Release Pull Request. -## Contributor Guidelines and Release Workflow +| Release Type | Trigger Prefix | Cadence | Execution | State Manipulation / Redeploy Required? | +| :--- | :--- | :--- | :--- | :--- | +| **Major (`vX.0.0`)** | `feat!:` or `BREAKING CHANGE:` | As needed | Automated prep, human merge | Yes | +| **Minor (`vX.Y.0`)** | `feat:` | As needed / Batch merged weekly | Automated prep, human merge | No | +| **Patch (`vX.Y.Z`)** | `fix:` | As needed | Automated prep, human merge | No | -To ensure smooth automated and manual releases, contributors must adhere to the following workflow: +--- + +## Contributor Guidelines and Release Workflow -1. Pull Request Impact Assessment: - * PR authors must explicitly state whether their proposed changes require state manipulation, state moves, or resource redeployment. - * If a PR introduces breaking state changes or resource redeployments, it must be flagged for inclusion in an upcoming Major Release. -2. Main Branch Readiness: - * All changes merged into the `main` branch should be tested and production-ready, as automated Minor Releases are generated directly from `main` on a monthly schedule. -3. Patch / Hotfix Workflow: - * Urgent fixes requiring a Patch Release are tagged manually ad-hoc against the affected version target and merged back to `main`. +To ensure smooth automated releases, contributors and maintainers must adhere to the following workflow: + +### 1. Pull Request Title Linting (Enforced) +To automate versioning accurately, all Pull Request titles must follow the **Conventional Commits** specification. The repository runs an automated **Pull Request Title Linter** on every PR to enforce this. + +* **Format:** `(): ` or `: ` +* **Allowed Types:** + * `feat`: A new feature (bumps Minor version) + * `fix`: A bug fix (bumps Patch version) + * `chore`: Maintenance tasks (no release) + * `docs`: Documentation changes (no release) + * `ci`: CI/CD workflow updates (no release) + * `test`: Adding or correcting tests (no release) + * `refactor`: Code refactoring without behavioral changes (no release) + * `style`: Code style changes, whitespace, formatting (no release) +* **Example:** `feat(kms): add support for HSM protection level` + +### 2. Squash Merging and Main Branch Cleanliness +To guarantee that the git history on `main` remains clean and compliant, the repository is configured to use **Squash and Merge**: +* When merging a pull request, the final squashed commit title is taken from the **PR Title**. +* Maintainers must verify that the PR title is clean and descriptive before clicking the merge button. + +### 3. Release Merging +* As compliant PRs are merged to `main`, Release Please updates a single open PR titled `chore: release vX.Y.Z`. +* When ready to publish the release, a maintainer merges the Release PR. This triggers GitHub Actions to automatically create the Git tag (e.g., `v1.3.0`) and publish the GitHub Release containing the compiled changelog. From f09d57a1e83e8c9ae4ac5c5e0c67a7f03d61bef4 Mon Sep 17 00:00:00 2001 From: Calvin Cheng Date: Fri, 11 Sep 2026 21:47:53 +0000 Subject: [PATCH 3/4] modules(kms): test custom modules changelog section --- modules/kms/versions.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/kms/versions.tf b/modules/kms/versions.tf index 2652f967b..d16cacf93 100644 --- a/modules/kms/versions.tf +++ b/modules/kms/versions.tf @@ -33,3 +33,5 @@ terraform { module_name = "google-pso-tool/cloud-foundation-fabric/modules/kms:v38.0.0-tf" } } + +# Test conventional commit tagging - modules type From dd915648ed52c83926fec60b99c2d35ea0e90c47 Mon Sep 17 00:00:00 2001 From: Calvin Cheng Date: Fri, 11 Sep 2026 21:47:55 +0000 Subject: [PATCH 4/4] blueprints(il5/bastion-pattern): test custom blueprints changelog section --- blueprints/il5/bastion-pattern/provider.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blueprints/il5/bastion-pattern/provider.tf b/blueprints/il5/bastion-pattern/provider.tf index 946323a13..5bf955a57 100644 --- a/blueprints/il5/bastion-pattern/provider.tf +++ b/blueprints/il5/bastion-pattern/provider.tf @@ -31,3 +31,5 @@ provider "google" { project = var.main_project_id region = var.region } + +# Test conventional commit tagging - blueprints type