Skip to content

feat: integrate auto-merge functionality and improve documentation#30

Merged
Laffs2k5 merged 12 commits intomainfrom
auto-merge-tidy-2
Mar 3, 2026
Merged

feat: integrate auto-merge functionality and improve documentation#30
Laffs2k5 merged 12 commits intomainfrom
auto-merge-tidy-2

Conversation

@Laffs2k5
Copy link
Copy Markdown
Contributor

@Laffs2k5 Laffs2k5 commented Feb 1, 2026

Summary

This PR introduces automated pull request merging capabilities for the terraform-ci-cd workflow. When enabled, PRs that meet configurable criteria (specific actors, change limits, successful workflow completion) can be automatically merged, reducing manual toil while maintaining safety guardrails.


✨ New Features

Auto-Merge Workflow Integration

A new automerge job is added to the terraform-ci-cd workflow that:

  • Runs only when pr-auto-merge-enabled: true
  • Only triggers on pull request events (not push or workflow_dispatch)
  • Skips closed or draft PRs
  • Requires all prior jobs to succeed before attempting merge

Three New Reusable Actions

Action Purpose
capture-matrix-job-meta Collects metadata from matrix job execution and stores it as artifacts for downstream processing. Captures information like plan change counts, which environments were processed, etc.
evaluate-automerge-eligibility Evaluates whether a PR meets the criteria for automatic merging based on configurable limits (max additions/deletions/modifications, allowed actors, etc.)
auto-merge-pr Performs the actual merge operation for eligible PRs using the GitHub API

Each action is:

  • Standalone with clear dependencies
  • Independently testable
  • Encapsulates its specific logic

New Workflow Inputs for Auto-Merge Configuration

pr-auto-merge-enabled: false  # Enable/disable auto-merge feature

pr-auto-merge-from-actors-yml: |  # Which actors can trigger auto-merge
  actors:
    - renovate[bot]
    - dependabot[bot]

pr-auto-merge-limits-yml: |  # Limits for when auto-merge is allowed
  max-additions: 10
  max-deletions: 10
  max-modifications: 5

Configurable GitHub App Credentials

Auto-merge requires a GitHub App token with contents: write and pull-requests: write permissions. Rather than hardcoding credentials, this PR introduces two new inputs that follow the established export-env-vars / extra-envs-from-secrets-yml pattern used elsewhere in this codebase:

pr-auto-merge-app-id: "12345"                            # GitHub App ID (string)
pr-auto-merge-app-private-key-secret: "MY_APP_PRIVATE_KEY"  # NAME of the secret, not the value

How it works:

  • pr-auto-merge-app-id is the numeric App ID, passed directly as a workflow input.
  • pr-auto-merge-app-private-key-secret holds the name of a GitHub Actions secret (not the value itself). The actual private key is resolved at runtime from the toJSON(secrets) context using jq, the same way export-env-vars resolves secret values from secret names. The resolved value is immediately masked via ::add-mask:: and passed as a step output using a random delimiter to safely handle multiline PEM keys.
  • Both inputs are validated as the first step of the automerge job so that misconfiguration fails fast with a clear error message before any other work is attempted.
  • The calling workflow must use secrets: inherit so the secret is available for resolution.

Example consumer usage:

uses: dsb-norge/github-actions-terraform/.github/workflows/terraform-ci-cd-default.yml@v0
with:
  pr-auto-merge-enabled: true
  pr-auto-merge-app-id: "12345"
  pr-auto-merge-app-private-key-secret: "MY_AUTOMERGE_APP_PRIVATE_KEY"
secrets: inherit

This design ensures:

  • No org-specific credentials are hardcoded in the reusable workflow
  • Each consumer provides their own GitHub App credentials
  • The secret value never appears in workflow inputs or logs
  • The pattern is consistent with existing secret handling in this codebase

🛠️ Improvements

Global Runner Configuration

  • Added new runs-on workflow input with default ubuntu-latest
  • Centralized runner configuration (single source of truth)
  • Per-environment overrides still possible via environments-yml
  • Removed redundant default assignment from create-tf-vars-matrix action

Skip Operations on Closed/Draft PRs

Workflow now skips expensive operations when:

  • PR action is closed
  • PR action is converted_to_draft

Affected steps: validation summary, terraform apply, terraform destroy. This prevents wasted compute on PRs that are no longer active.


📝 Documentation & Code Quality

Fixed Typos and Incorrect References

  • passepassed (secrets comment)
  • triggerdtriggered (add-pr-comment description)
  • woraroundworkaround (setup-terraform comment)
  • Fixed incorrect goals-yml references to correct field names

Improved Documentation

  • Reordered environment settings alphabetically for better discoverability
  • Documented previously undocumented per-environment settings:
    • terraform-version
    • tflint-version
    • format-check-in-root-dir
    • add-pr-comment

Code Organization

  • Alphabetically ordered input field arrays in create-tf-vars-matrix for maintainability:
    • YML_INPUTS
    • MERGE_INPUT_YML_FIELDS
    • REQ_FIELDS
    • NOT_EMPTY_FIELDS
  • Added documentation comments clarifying deliberately excluded fields

🔄 How Auto-Merge Works

flowchart TD
    A[PR Event] --> B[create-matrix job]
    B --> C[terraform-ci-cd job]
    C --> D[Capture metadata<br/>for each matrix env]
    D --> E[conclusion job]
    E --> F{Conclusion<br/>succeeded?}
    F -->|No| G[❌ Workflow ends<br/>no auto-merge]
    F -->|Yes| H{Auto-merge<br/>enabled?}
    H -->|No| I[✅ Workflow ends<br/>auto-merge disabled]
    H -->|Yes| J{PR event &<br/>not closed/draft?}
    J -->|No| I
    J -->|Yes| K[automerge job starts]
    K --> L[🔐 Validate credentials config]
    L --> M[📥 Download metadata artifacts]
    M --> N[🔍 Evaluate eligibility:<br/>• Actor allowed?<br/>• Plan within limits?]
    N --> O{Eligible?}
    O -->|No| P[📋 Log reason & skip]
    O -->|Yes| Q[🔑 Resolve app private key<br/>from secrets context]
    Q --> R[🎫 Create GitHub App token]
    R --> S[🤖 Perform auto-merge]
Loading

Job Execution Order

Order Job Runs When
1 create-matrix Always
2 terraform-ci-cd Always (matrix job per environment)
3 conclusion Always (determines overall success/failure)
4 automerge Only if: conclusion succeeded ✓ AND pr-auto-merge-enabled ✓ AND PR event ✓ AND not closed/draft ✓

Eligibility Criteria

Within the automerge job, a PR is eligible for auto-merge when:

  1. ✅ Triggered by an allowed actor (configurable via pr-auto-merge-from-actors-yml)
  2. ✅ Plan changes within configured limits (configurable via pr-auto-merge-limits-yml)

Automerge Job Step Sequence

Step Condition Purpose
🔐 Validate config Always Fail-fast if pr-auto-merge-app-id or pr-auto-merge-app-private-key-secret is missing
📥 Download metadata Always Download per-environment metadata artifacts from matrix jobs
🔍 Evaluate eligibility Always Check actor and plan-change limits; outputs is-eligible
🔑 Resolve private key is-eligible == 'true' Resolve secret value from toJSON(secrets) by name, mask it
🎫 Create App token is-eligible == 'true' Generate scoped GitHub App installation token
🤖 Auto-merge PR is-eligible == 'true' Perform gh pr merge --admin --rebase --delete-branch

📋 Commits (Logical Grouping)

Preparatory Refactoring

  1. docs: fix typos and field references in workflow - Non-functional cleanup
  2. docs: reorder environment settings alphabetically - Documentation improvements
  3. refactor: reorder input fields in create-tf-vars-matrix - Alphabetical ordering for maintainability

Infrastructure Improvements

  1. feat: add global runs-on input to workflow - Centralized runner configuration
  2. feat: skip operations when PR closed or draft - Resource optimization

New Actions (Standalone, Testable)

  1. feat: add capture-matrix-job-meta action - Metadata collection
  2. feat: add evaluate-automerge-eligibility action - Eligibility evaluation
  3. feat: add auto-merge-pr action - Merge execution

Feature Integration

  1. feat: add PR auto-merge configuration inputs - Configuration infrastructure
  2. feat: integrate auto-merge workflow - Final activation
  3. feat: make auto-merge GitHub App credentials configurable - Configurable credentials following export-env-vars pattern

🧪 Testing

  • Each new action includes test scaffolding (run_all_tests.sh, run_local_step_*.sh)
  • Actions can be tested independently before workflow integration
  • Feature is opt-in via pr-auto-merge-enabled input (default: false)

⚠️ Notes

  • The debug: use dev tag in cicd wf commit is temporary for testing and will be reverted before final merge

Copy link
Copy Markdown
Contributor

@Artlvns Artlvns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Masterpiece 🚀 🏆

Laffs2k5 added 10 commits March 3, 2026 08:42
Non-functional cleanup that improves readability and correctness:
- Fixed typo 'passe' → 'passed' in secrets comment
- Fixed typo 'triggerd' → 'triggered' in add-pr-comment description
- Fixed typo 'woraround' → 'workaround' in setup-terraform comment
- Fixed incorrect description reference 'goals-yml' → 'terraform-init-additional-dirs-yml'
- Fixed incorrect description reference 'goals-yml' → 'extra-envs-yml'
- Fixed incorrect description reference 'goals-yml' → 'extra-envs-from-secrets-yml'
Improves consistency and readability in documentation:
- Reordered optional environment fields alphabetically for better discoverability
- Documented previously undocumented per-environment settings:
  - terraform-version
  - tflint-version
  - format-check-in-root-dir
  - add-pr-comment
- Updated runs-on description to reference the workflow input instead of full URL
Organize input fields alphabetically and add documentation comments:
- Added comment documenting deliberately excluded fields
- Reordered YML_INPUTS alphabetically
- Reordered MERGE_INPUT_YML_FIELDS alphabetically
- Updated comment to clarify 'yml fields that needs merge'
- Reordered REQ_FIELDS alphabetically
- Reordered NOT_EMPTY_FIELDS alphabetically

Alphabetical ordering improves maintainability and makes it easier
to spot missing or duplicate fields. No functional changes.
Centralize runner configuration with global default:
- Added new workflow input 'runs-on' with default 'ubuntu-latest'
- Updated 'create-matrix' job to use global runs-on input
- Updated 'conclusion' job to use global runs-on input
- Removed default 'ubuntu-latest' assignment from create-tf-vars-matrix action

Single source of truth for runner configuration. Per-environment override
still possible via environments-yml. Simplifies create-tf-vars-matrix action.
All runner-related changes grouped together.
Prevent unnecessary operations when PR is being closed or converted to draft:
- Updated validation summary step to skip when action is 'closed' or 'converted_to_draft'
- Updated apply step to skip when action is 'closed' or 'converted_to_draft'
- Updated destroy step to skip when action is 'closed' or 'converted_to_draft'

Independent improvement to workflow logic that prevents wasted resources
on PRs being closed. No dependencies on auto-merge feature.
Introduce new reusable action for capturing matrix job metadata.

This standalone action collects metadata from matrix job execution,
storing it as artifacts for use by downstream processes. It enables
future metadata collection use cases without modifying the main workflow.

Benefits:
- Standalone action with no dependencies
- Can be tested independently
- Enables metadata-driven automation
- Does not modify existing workflow (integration comes later)
Introduce new reusable action for evaluating PR auto-merge eligibility.

This standalone action evaluates whether a pull request meets the criteria
for automatic merging based on metadata from capture-matrix-job-meta and
configurable limits (actors, plan counts, etc.).

Benefits:
- Standalone action with clear dependencies (metadata format from capture action)
- Can be tested independently
- Encapsulates complex eligibility logic
- Does not modify existing workflow (integration comes later)
Introduce new reusable action for performing PR auto-merge.

This standalone action handles the actual merge operation for pull requests
that have been evaluated as eligible for automatic merging. It encapsulates
the merge logic and GitHub API interactions.

Benefits:
- Standalone action with no dependencies
- Can be tested independently
- Encapsulates merge logic
- Does not modify existing workflow (integration comes later)
Add configuration inputs for auto-merge behavior without activating it:
- Added workflow inputs: pr-auto-merge-enabled, pr-auto-merge-from-actors-yml, pr-auto-merge-limits-yml
- Added corresponding parsing/validation in create-tf-vars-matrix:
  - Included in YML_INPUTS and merge lists
  - Required and non-empty field validations for pr-auto-merge-* values

Adds configuration infrastructure for auto-merge; feature integration comes later.
Activate auto-merge functionality by integrating new actions:
- Capture matrix job metadata in terraform-ci-cd job (always, non-blocking)
- Add automerge job gated on pr-auto-merge-enabled, PR event, non-closed/draft, and successful workflow
- Download metadata artifacts, evaluate eligibility, mint GitHub App token, and perform auto-merge

Completes integration of capture/evaluate/merge actions with configurable auto-merge inputs.
@Laffs2k5 Laffs2k5 force-pushed the auto-merge-tidy-2 branch from 3057d96 to a3d9224 Compare March 3, 2026 07:43
Laffs2k5 added 2 commits March 3, 2026 13:37
Replace hardcoded app-id and PRIVATE_KEY secret with two new workflow inputs:
- pr-auto-merge-app-id: GitHub App ID (plain string)
- pr-auto-merge-app-private-key-secret: name of the secret containing the private key

The private key is resolved at runtime from toJSON(secrets), following the same pattern used by export-env-vars for extra-envs-from-secrets-yml.

A validation step now runs first in the automerge job, failing early with a clear error if auto-merge is enabled but the required configuration is missing.
@Laffs2k5 Laffs2k5 force-pushed the auto-merge-tidy-2 branch from c4ff28c to 664559a Compare March 3, 2026 12:37
@Laffs2k5 Laffs2k5 marked this pull request as ready for review March 3, 2026 12:41
@Laffs2k5 Laffs2k5 merged commit 12109f9 into main Mar 3, 2026
@Laffs2k5 Laffs2k5 deleted the auto-merge-tidy-2 branch March 3, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants