From 54f1ff0ceffcac34e81e30cfd0df046a92a42fe3 Mon Sep 17 00:00:00 2001 From: Luca Bello Date: Tue, 21 Apr 2026 10:51:55 +0200 Subject: [PATCH 1/4] feat(ci): add automatic terraform tagging on charm release --- .../workflows/_charm-terraform-release.yaml | 68 +++++++++++++++++++ .github/workflows/charm-release.yaml | 23 +++++++ 2 files changed, 91 insertions(+) create mode 100644 .github/workflows/_charm-terraform-release.yaml diff --git a/.github/workflows/_charm-terraform-release.yaml b/.github/workflows/_charm-terraform-release.yaml new file mode 100644 index 00000000..03e35b9e --- /dev/null +++ b/.github/workflows/_charm-terraform-release.yaml @@ -0,0 +1,68 @@ +name: Release Terraform module + +on: + workflow_call: + inputs: + terraform-tag-prefix: + description: "Tag prefix to use for the Terraform release tag." + default: 'tf-' + required: false + type: string + terraform-tag-suffix: + description: "Tag suffix to append to the Terraform release tag." + default: '' + required: false + type: string + charm-path: + description: "Path to the charm directory containing the terraform/ folder." + default: '.' + required: false + type: string + +permissions: + contents: write + +jobs: + release: + name: Release the Terraform module + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Check for terraform changes + id: check-changes + working-directory: ${{ inputs.charm-path }} + run: | + # Check if the push includes changes to terraform/ + if git diff --name-only HEAD~1..HEAD | grep -q '^terraform/'; then + echo "changed=true" >> "$GITHUB_OUTPUT" + else + echo "changed=false" >> "$GITHUB_OUTPUT" + fi + - name: Create Terraform tag + if: steps.check-changes.outputs.changed == 'true' + working-directory: ${{ inputs.charm-path }} + env: + TAG_PREFIX: ${{ inputs.terraform-tag-prefix }} + TAG_SUFFIX: ${{ inputs.terraform-tag-suffix }} + GIT_BRANCH: ${{ github.ref_name }} + run: | + # Extract semantic version from the track branch name + track_version="${GIT_BRANCH#track/}" + # Calculate patch version: number of commits touching terraform/ since diverging from main + git fetch origin main + merge_base=$(git merge-base HEAD origin/main) + patch=$(git rev-list --count "$merge_base"..HEAD -- terraform/) + # Build the tag + tag="${TAG_PREFIX}${track_version}.${patch}${TAG_SUFFIX}" + echo "Creating tag: $tag" + # Configure git with noctua bot identity + git config --global user.email "webops+observability-noctua-bot@canonical.com" + git config --global user.name "Noctua" + # Create and push the annotated tag + git log -1 --pretty=%B > tag-message + git tag --annotate "$tag" --file=tag-message + rm -f tag-message + git push origin "$tag" diff --git a/.github/workflows/charm-release.yaml b/.github/workflows/charm-release.yaml index 6b36ce5a..bc4aa625 100644 --- a/.github/workflows/charm-release.yaml +++ b/.github/workflows/charm-release.yaml @@ -64,6 +64,16 @@ on: default: false required: false type: boolean + terraform-tag-prefix: + description: "Tag prefix to use for the Terraform release tag." + default: 'tf-' + required: false + type: string + terraform-tag-suffix: + description: "Tag suffix to append to the Terraform release tag." + default: '' + required: false + type: string secrets: CHARMHUB_TOKEN: required: true @@ -226,3 +236,16 @@ jobs: fi done fi + + release-terraform: + name: Release the Terraform module + needs: + - release-charm + if: github.ref_name != 'main' && startsWith(github.ref_name, 'track/') + uses: ./.github/workflows/_charm-terraform-release.yaml + permissions: + contents: write + with: + terraform-tag-prefix: "${{ inputs.terraform-tag-prefix }}" + terraform-tag-suffix: "${{ inputs.terraform-tag-suffix }}" + charm-path: "${{ inputs.charm-path }}" From 65165ef45c78a3d0843c1f16c7ef91143410a892 Mon Sep 17 00:00:00 2001 From: Luca Bello Date: Thu, 23 Apr 2026 13:27:27 +0200 Subject: [PATCH 2/4] refactor(ci): make terraform release workflow public Rename _charm-terraform-release.yaml to terraform-release.yaml so it can be called directly by repositories that have a Terraform module but no charm module. Rename the 'charm-path' input to 'root-path' to reflect that the caller is not necessarily a charm repository. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/charm-release.yaml | 4 ++-- ...harm-terraform-release.yaml => terraform-release.yaml} | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename .github/workflows/{_charm-terraform-release.yaml => terraform-release.yaml} (91%) diff --git a/.github/workflows/charm-release.yaml b/.github/workflows/charm-release.yaml index bc4aa625..94623303 100644 --- a/.github/workflows/charm-release.yaml +++ b/.github/workflows/charm-release.yaml @@ -242,10 +242,10 @@ jobs: needs: - release-charm if: github.ref_name != 'main' && startsWith(github.ref_name, 'track/') - uses: ./.github/workflows/_charm-terraform-release.yaml + uses: ./.github/workflows/terraform-release.yaml permissions: contents: write with: terraform-tag-prefix: "${{ inputs.terraform-tag-prefix }}" terraform-tag-suffix: "${{ inputs.terraform-tag-suffix }}" - charm-path: "${{ inputs.charm-path }}" + root-path: "${{ inputs.charm-path }}" diff --git a/.github/workflows/_charm-terraform-release.yaml b/.github/workflows/terraform-release.yaml similarity index 91% rename from .github/workflows/_charm-terraform-release.yaml rename to .github/workflows/terraform-release.yaml index 03e35b9e..55e1c149 100644 --- a/.github/workflows/_charm-terraform-release.yaml +++ b/.github/workflows/terraform-release.yaml @@ -13,8 +13,8 @@ on: default: '' required: false type: string - charm-path: - description: "Path to the charm directory containing the terraform/ folder." + root-path: + description: "Path to the root directory containing the terraform/ folder." default: '.' required: false type: string @@ -33,7 +33,7 @@ jobs: fetch-depth: 0 - name: Check for terraform changes id: check-changes - working-directory: ${{ inputs.charm-path }} + working-directory: ${{ inputs.root-path }} run: | # Check if the push includes changes to terraform/ if git diff --name-only HEAD~1..HEAD | grep -q '^terraform/'; then @@ -43,7 +43,7 @@ jobs: fi - name: Create Terraform tag if: steps.check-changes.outputs.changed == 'true' - working-directory: ${{ inputs.charm-path }} + working-directory: ${{ inputs.root-path }} env: TAG_PREFIX: ${{ inputs.terraform-tag-prefix }} TAG_SUFFIX: ${{ inputs.terraform-tag-suffix }} From d6fafcf1378123d2a33c0c0b50dfc0e122051c84 Mon Sep 17 00:00:00 2001 From: Luca Bello Date: Thu, 23 Apr 2026 14:05:29 +0200 Subject: [PATCH 3/4] refactor(ci): rename root-path input to terraform-path The terraform-release workflow now accepts a direct path to the terraform directory (defaulting to 'terraform') via the terraform-path input, instead of a root directory that implicitly contains terraform/. The charm-release caller passes '/terraform' accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/charm-release.yaml | 2 +- .github/workflows/terraform-release.yaml | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/charm-release.yaml b/.github/workflows/charm-release.yaml index 94623303..037e044b 100644 --- a/.github/workflows/charm-release.yaml +++ b/.github/workflows/charm-release.yaml @@ -248,4 +248,4 @@ jobs: with: terraform-tag-prefix: "${{ inputs.terraform-tag-prefix }}" terraform-tag-suffix: "${{ inputs.terraform-tag-suffix }}" - root-path: "${{ inputs.charm-path }}" + terraform-path: "${{ inputs.charm-path }}/terraform" diff --git a/.github/workflows/terraform-release.yaml b/.github/workflows/terraform-release.yaml index 55e1c149..e115e0e9 100644 --- a/.github/workflows/terraform-release.yaml +++ b/.github/workflows/terraform-release.yaml @@ -13,9 +13,9 @@ on: default: '' required: false type: string - root-path: - description: "Path to the root directory containing the terraform/ folder." - default: '.' + terraform-path: + description: "Path to the terraform directory, relative to the repository root." + default: 'terraform' required: false type: string @@ -33,28 +33,29 @@ jobs: fetch-depth: 0 - name: Check for terraform changes id: check-changes - working-directory: ${{ inputs.root-path }} + env: + TERRAFORM_PATH: ${{ inputs.terraform-path }} run: | - # Check if the push includes changes to terraform/ - if git diff --name-only HEAD~1..HEAD | grep -q '^terraform/'; then + # Check if the push includes changes to the terraform directory + if git diff --name-only HEAD~1..HEAD | grep -q "^${TERRAFORM_PATH}/"; then echo "changed=true" >> "$GITHUB_OUTPUT" else echo "changed=false" >> "$GITHUB_OUTPUT" fi - name: Create Terraform tag if: steps.check-changes.outputs.changed == 'true' - working-directory: ${{ inputs.root-path }} env: + TERRAFORM_PATH: ${{ inputs.terraform-path }} TAG_PREFIX: ${{ inputs.terraform-tag-prefix }} TAG_SUFFIX: ${{ inputs.terraform-tag-suffix }} GIT_BRANCH: ${{ github.ref_name }} run: | # Extract semantic version from the track branch name track_version="${GIT_BRANCH#track/}" - # Calculate patch version: number of commits touching terraform/ since diverging from main + # Calculate patch version: number of commits touching terraform dir since diverging from main git fetch origin main merge_base=$(git merge-base HEAD origin/main) - patch=$(git rev-list --count "$merge_base"..HEAD -- terraform/) + patch=$(git rev-list --count "$merge_base"..HEAD -- "$TERRAFORM_PATH/") # Build the tag tag="${TAG_PREFIX}${track_version}.${patch}${TAG_SUFFIX}" echo "Creating tag: $tag" From 2db59fb38935e88318b5acd663514c50093dae30 Mon Sep 17 00:00:00 2001 From: Luca Bello Date: Mon, 27 Apr 2026 11:05:12 +0200 Subject: [PATCH 4/4] feat(ci): restrict terraform tagging to track/. branches Add a branch-format validation step in terraform-release.yaml that checks github.ref_name against ^track/[0-9]+\.[0-9]+$ before proceeding. This ensures branches like track/2 or track/main don't trigger tagging, while track/2.0 and track/1.3 are accepted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/terraform-release.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/terraform-release.yaml b/.github/workflows/terraform-release.yaml index e115e0e9..3ff9fefc 100644 --- a/.github/workflows/terraform-release.yaml +++ b/.github/workflows/terraform-release.yaml @@ -31,7 +31,20 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Validate branch format + id: validate-branch + env: + GIT_BRANCH: ${{ github.ref_name }} + run: | + # Only allow tagging on branches matching track/. + if [[ "$GIT_BRANCH" =~ ^track/[0-9]+\.[0-9]+$ ]]; then + echo "valid=true" >> "$GITHUB_OUTPUT" + else + echo "Branch '$GIT_BRANCH' does not match track/. format. Skipping." + echo "valid=false" >> "$GITHUB_OUTPUT" + fi - name: Check for terraform changes + if: steps.validate-branch.outputs.valid == 'true' id: check-changes env: TERRAFORM_PATH: ${{ inputs.terraform-path }} @@ -43,7 +56,7 @@ jobs: echo "changed=false" >> "$GITHUB_OUTPUT" fi - name: Create Terraform tag - if: steps.check-changes.outputs.changed == 'true' + if: steps.validate-branch.outputs.valid == 'true' && steps.check-changes.outputs.changed == 'true' env: TERRAFORM_PATH: ${{ inputs.terraform-path }} TAG_PREFIX: ${{ inputs.terraform-tag-prefix }}