From 12b58980e004364274cd9382ac88de0ffb6ef932 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 22:22:35 +0000 Subject: [PATCH 01/18] Improve Patcher documentation: clarify use cases and add simplified GitHub Actions guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add new 'GitHub Actions for Continuous Updates' guide for teams wanting to keep entire codebase current - Update promotion workflows guide to clarify it's for environment-specific promotion (dev → stage → prod) - Add clear distinction between two primary Patcher use cases: upgrading out-of-date code vs maintaining current code - Update sidebar navigation to include new guide as first option in Guides section - Add cross-references between the two approaches to help users choose the right workflow Co-Authored-By: Josh Padnick --- .../github-actions-continuous-updates.md | 171 ++++++++++++++++++ .../patcher/guides/promotion-workflows.md | 15 +- sidebars/docs.js | 5 + 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md diff --git a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md new file mode 100644 index 000000000..47e9e6fe3 --- /dev/null +++ b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md @@ -0,0 +1,171 @@ +# GitHub Actions for Continuous Updates + +:::info +This guide covers setting up GitHub Actions to keep your infrastructure code up to date over time. If you need to promote updates across multiple environments (dev → stage → prod), see [Setting up Promotion Workflows](/2.0/docs/patcher/guides/promotion-workflows). +::: + +**Related content**: +* [Concepts - Patcher Workflows](/2.0/docs/patcher/concepts/promotion-workflows) +* [Architecture - Overview](/2.0/docs/patcher/architecture) + +## Overview + +Patcher excels at keeping your infrastructure code current by automatically detecting and applying dependency updates. This guide shows you how to set up a GitHub Actions workflow that scans your entire repository for outdated dependencies and creates pull requests to keep everything up to date. + +This approach is ideal for teams that want to: +- Maintain current dependencies across their entire codebase +- Receive regular automated updates without manual intervention +- Keep security vulnerabilities and technical debt to a minimum + +## Prerequisites + +### Infrastructure as Code +Your codebase should be structured as infrastructure as code (IaC) using tools like Terraform, OpenTofu, or Terragrunt. This setup allows Patcher to automate updates across your infrastructure. + +### GitHub Repository Setup +- Your infrastructure code should be in a GitHub repository +- You'll need a GitHub token with appropriate permissions to create pull requests +- For Gruntwork customers, you'll need a `PIPELINES_READ_TOKEN` to access Patcher + +## Implementation + +The GitHub Actions workflow consists of two main jobs: + +1. **`patcher-report`**: Scans your entire repository for outdated dependencies +2. **`update-dependencies`**: Creates individual pull requests for each dependency that needs updating + +### Basic Workflow Setup + +Create a new file `.github/workflows/patcher-continuous-updates.yml` in your repository: + +```yml +name: Patcher Continuous Updates + +on: + workflow_dispatch: + repository_dispatch: + types: [new_module_release] + schedule: + # Run every Monday at 04:15 UTC + - cron: "15 4 * * 1" + +permissions: + contents: write + pull-requests: write + +jobs: + patcher-report: + runs-on: ubuntu-latest + outputs: + spec: ${{ steps.get-spec.outputs.spec }} + steps: + - uses: actions/checkout@v4 + - uses: gruntwork-io/patcher-action@v2 + id: get-spec + with: + patcher_command: report + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + working_dir: ./ + spec_file: /tmp/patcher-spec.json + + update-dependencies: + needs: [patcher-report] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + dependency: ${{ fromJson(needs.patcher-report.outputs.spec).Dependencies }} + steps: + - uses: actions/checkout@v4 + + - name: Create the spec file + shell: bash + run: | + echo '${{ needs.patcher-report.outputs.spec }}' > /tmp/patcher-spec.json + + - uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: update + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + working_dir: ./ + dependency: ${{ matrix.dependency.ID }} + spec_file: /tmp/patcher-spec.json + pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" + pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" +``` + +## Key Configuration Options + +### Scheduling +The workflow is configured to run: +- **Manually**: Using `workflow_dispatch` for testing +- **On new releases**: Via `repository_dispatch` when Gruntwork releases new modules +- **Scheduled**: Every Monday at 04:15 UTC (customize as needed) + +### Authentication +- `PIPELINES_READ_TOKEN`: Required for Gruntwork customers to access Patcher and download dependencies +- The token needs `contents: write` and `pull-requests: write` permissions + +### Working Directory +- `working_dir: ./` scans the entire repository +- You can specify a subdirectory if your infrastructure code is in a specific folder + +### Pull Request Strategy +- Creates one pull request per dependency +- Uses descriptive branch names: `patcher-updates-{dependency-id}` +- Includes clear titles indicating which dependency is being updated + +## Customization Options + +### Filtering Dependencies +If you want to exclude certain directories or files, you can add filtering: + +```yml +- uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: report + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + exclude_dirs: "examples/**,tests/**" + working_dir: ./ + spec_file: /tmp/patcher-spec.json +``` + +### Update Strategies +Control how aggressively Patcher updates dependencies: + +```yml +- uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: update + update_strategy: next-safe # or "next-breaking" + # ... other parameters +``` + +### Dry Run Mode +Test your workflow without creating actual pull requests: + +```yml +- uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: update + dry_run: true + # ... other parameters +``` + +## Environment-Specific Updates + +If you need to promote updates across multiple environments (dev → stage → prod) rather than updating everything at once, see the [Setting up Promotion Workflows](/2.0/docs/patcher/guides/promotion-workflows) guide. That approach provides: + +- Environment-specific scanning and updates +- Controlled promotion between environments +- Validation gates between each environment + +## Next Steps + +1. **Set up the workflow**: Add the YAML file to your repository +2. **Configure secrets**: Add your `PIPELINES_READ_TOKEN` to GitHub secrets +3. **Test manually**: Use the "Run workflow" button to test the setup +4. **Review pull requests**: Patcher will create PRs for each outdated dependency +5. **Merge updates**: Review and merge the pull requests to apply updates + +The workflow will automatically run on your configured schedule, keeping your infrastructure dependencies current with minimal manual intervention. diff --git a/docs/2.0/docs/patcher/guides/promotion-workflows.md b/docs/2.0/docs/patcher/guides/promotion-workflows.md index a2f18d488..b38b12cac 100644 --- a/docs/2.0/docs/patcher/guides/promotion-workflows.md +++ b/docs/2.0/docs/patcher/guides/promotion-workflows.md @@ -1,12 +1,25 @@ # Using Patcher Promotion Workflows +:::info +This guide covers setting up promotion workflows to move updates across multiple environments (dev → stage → prod). If you want to keep your entire codebase up to date without environment-specific promotion, see [GitHub Actions for Continuous Updates](/2.0/docs/patcher/guides/github-actions-continuous-updates). +::: + :::info As of July 2024, Gruntwork officially supports Patcher Promotion Workflows using GitHub Actions. Support for other CI systems will be introduced in future releases. ::: **Related content**: * [Concepts - Patcher Workflows](/2.0/docs/patcher/concepts/promotion-workflows) -* [Architecture - Overview](/2.0/docs/patcher/architecture) +* [Architecture - Overview](/2.0/docs/patcher/architecture) + +## When to Use Promotion Workflows + +Patcher supports two primary use cases: + +1. **Upgrading very out-of-date infrastructure code**: For codebases that haven't been updated in a while +2. **Keeping infrastructure code up to date over time**: For ongoing maintenance and security + +Patcher excels at the second use case. Promotion workflows are specifically designed for teams that need to validate changes across multiple environments before reaching production. If you simply want to keep your entire codebase current without environment-specific validation, consider using the [simpler continuous updates approach](/2.0/docs/patcher/guides/github-actions-continuous-updates) instead. ## Prerequisites ### Infrastructure as Code diff --git a/sidebars/docs.js b/sidebars/docs.js index 5831b4a4c..20c4fb406 100644 --- a/sidebars/docs.js +++ b/sidebars/docs.js @@ -571,6 +571,11 @@ const sidebar = [ type: "category", collapsed: true, items: [ + { + label: "GitHub Actions for Continuous Updates", + type: "doc", + id: "2.0/docs/patcher/guides/github-actions-continuous-updates", + }, { label: "Setting up Promotion Workflows", type: "doc", From 5f7bb89a0c128acbf1fb706fd315a085a095f386 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 30 Aug 2025 01:38:49 +0000 Subject: [PATCH 02/18] Fix spellcheck error and add GitHub fine-grained token setup documentation - Fix typo 'leasat' -> 'least' in accountfactory drift remediation guide - Add comprehensive GitHub Enterprise fine-grained token setup section to Patcher continuous updates guide - Include step-by-step instructions for token creation with required permissions - Focus on organization's patcher-cli and terrapatch-cli repositories only Co-Authored-By: Josh Padnick --- .../drift-remediation-with-async-module.md | 2 +- .../github-actions-continuous-updates.md | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/2.0/docs/accountfactory/guides/drift-remediation-with-async-module.md b/docs/2.0/docs/accountfactory/guides/drift-remediation-with-async-module.md index 5870c1670..b46975469 100644 --- a/docs/2.0/docs/accountfactory/guides/drift-remediation-with-async-module.md +++ b/docs/2.0/docs/accountfactory/guides/drift-remediation-with-async-module.md @@ -134,7 +134,7 @@ For `_envcommon/landingzone/root-pipelines-apply-role.hcl`, ensure that you have } ``` -For `_envcommon/landingzone/root-pipelines-plan-role.hcl`, ensure that you have at leasat the following permissions: +For `_envcommon/landingzone/root-pipelines-plan-role.hcl`, ensure that you have at least the following permissions: ```hcl "CloudWatchEventsReadOnlyAccess" = { diff --git a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md index 47e9e6fe3..5071a4139 100644 --- a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md +++ b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md @@ -27,6 +27,43 @@ Your codebase should be structured as infrastructure as code (IaC) using tools l - You'll need a GitHub token with appropriate permissions to create pull requests - For Gruntwork customers, you'll need a `PIPELINES_READ_TOKEN` to access Patcher +### GitHub Fine-Grained Personal Access Token Setup + +For GitHub Enterprise users, you'll need to create a fine-grained personal access token with specific permissions. Follow these steps: + +1. **Navigate to GitHub Settings** + - Go to your GitHub Enterprise instance + - Click your profile picture → **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens** + +2. **Create New Token** + - Click **Generate new token** + - Select **Fine-grained personal access token** + +3. **Configure Token Settings** + - **Token name**: Choose a descriptive name (e.g., "Patcher CI Token") + - **Expiration**: Set to **90 days** or longer based on your security policy + - **Resource owner**: Select your organization + +4. **Repository Access** + Configure access to the following repositories: + - **Your organization's patcher-cli repository** (typically `gruntwork-io/patcher-cli` or your custom org) + - **Your organization's terrapatch-cli repository** (typically `gruntwork-io/terrapatch-cli` or your custom org) + +5. **Set Required Permissions** + Under "Permissions", configure these **Repository permissions**: + - **Contents**: **Read** access + - **Metadata**: **Read** access + - **Actions**: **Read** access (for downloading releases) + +6. **Generate and Store Token** + - Click **Generate token** + - **Copy the token immediately** (you won't be able to see it again) + - Store it securely as a GitHub secret named `PIPELINES_READ_TOKEN` in your repository + +:::warning +Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. +::: + ## Implementation The GitHub Actions workflow consists of two main jobs: From c585c8460771f8db6a59059951e5649c6c91c237 Mon Sep 17 00:00:00 2001 From: Josh Padnick Date: Tue, 2 Sep 2025 09:29:05 -0700 Subject: [PATCH 03/18] Add warning on github org --- .../docs/patcher/guides/github-actions-continuous-updates.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md index 5071a4139..997e9e472 100644 --- a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md +++ b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md @@ -43,6 +43,9 @@ For GitHub Enterprise users, you'll need to create a fine-grained personal acces - **Token name**: Choose a descriptive name (e.g., "Patcher CI Token") - **Expiration**: Set to **90 days** or longer based on your security policy - **Resource owner**: Select your organization + :::warning + It's easy to not select the right organization! Be sure to select the GitHub org -- not your username -- that actually holds the repos you're looking to access. + ::: 4. **Repository Access** Configure access to the following repositories: From b4b5fe87cb6d6e996723850a41f9873279620005 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 16:52:39 +0000 Subject: [PATCH 04/18] Add patcher-action v2 to v3 migration documentation - Document key breaking changes: token consolidation, parameter renames - Add before/after workflow examples for easy migration - Include custom organization setup instructions for v3 - Update existing workflow examples to use v3 syntax - Provide migration checklist for systematic upgrade process Co-Authored-By: Josh Padnick --- .../github-actions-continuous-updates.md | 109 ++++++++++++++++-- 1 file changed, 99 insertions(+), 10 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md index 5071a4139..07a12543c 100644 --- a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md +++ b/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md @@ -97,11 +97,11 @@ jobs: spec: ${{ steps.get-spec.outputs.spec }} steps: - uses: actions/checkout@v4 - - uses: gruntwork-io/patcher-action@v2 + - uses: gruntwork-io/patcher-action@v3 id: get-spec with: patcher_command: report - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ spec_file: /tmp/patcher-spec.json @@ -120,17 +120,106 @@ jobs: run: | echo '${{ needs.patcher-report.outputs.spec }}' > /tmp/patcher-spec.json - - uses: gruntwork-io/patcher-action@v2 + - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ dependency: ${{ matrix.dependency.ID }} spec_file: /tmp/patcher-spec.json - pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" - pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" + pr_title: "[Patcher] Update ${{ matrix.dependency.ID }}" + pr_target_branch: "patcher-updates-${{ matrix.dependency.ID }}" ``` +## Migrating from v2 to v3 + +:::info +Patcher Action v3 introduces breaking changes that require updating your workflow configuration. This section helps you migrate from v2 to v3. +::: + +### Key Breaking Changes + +**1. Token Consolidation** +- **v2**: Used separate `github_token`, `read_token`, and `update_token` inputs +- **v3**: Uses a single `auth_token` input for all authentication + +**2. Parameter Renames** +- `pull_request_branch` → `pr_target_branch` +- `pull_request_title` → `pr_title` + +**3. New Custom Organization Support** +- `github_org`: Specify custom organization (defaults to "gruntwork-io") +- `github_base_url`: Support for GitHub Enterprise instances +- `patcher_git_repo` / `terrapatch_git_repo`: Custom repository names +- `terrapatch_github_org`: Separate organization for terrapatch + +### Migration Examples + +**Before (v2):** +```yml +- uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: report + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + working_dir: ./ + spec_file: /tmp/patcher-spec.json + +- uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: update + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + dependency: ${{ matrix.dependency.ID }} + spec_file: /tmp/patcher-spec.json + pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" + pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" +``` + +**After (v3):** +```yml +- uses: gruntwork-io/patcher-action@v3 + with: + patcher_command: report + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + working_dir: ./ + spec_file: /tmp/patcher-spec.json + +- uses: gruntwork-io/patcher-action@v3 + with: + patcher_command: update + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + dependency: ${{ matrix.dependency.ID }} + spec_file: /tmp/patcher-spec.json + pr_title: "[Patcher] Update ${{ matrix.dependency.ID }}" + pr_target_branch: "patcher-updates-${{ matrix.dependency.ID }}" +``` + +### Custom Organization Setup (v3 Only) + +For GitHub Enterprise or custom organizations: + +```yml +- uses: gruntwork-io/patcher-action@v3 + with: + patcher_command: report + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + github_base_url: "https://github.company.com" + github_org: "my-custom-org" + patcher_git_repo: "patcher-cli" + terrapatch_git_repo: "terrapatch-cli" + terrapatch_github_org: "my-custom-org" # Optional: defaults to github_org + working_dir: ./ + spec_file: /tmp/patcher-spec.json +``` + +### Migration Checklist + +- [ ] Replace `github_token` with `auth_token` in all patcher-action steps +- [ ] Update `pull_request_branch` to `pr_target_branch` +- [ ] Update `pull_request_title` to `pr_title` +- [ ] Update action version from `@v2` to `@v3` +- [ ] Configure custom organization settings if needed (GitHub Enterprise users) +- [ ] Test the updated workflow with a manual trigger + ## Key Configuration Options ### Scheduling @@ -158,10 +247,10 @@ The workflow is configured to run: If you want to exclude certain directories or files, you can add filtering: ```yml -- uses: gruntwork-io/patcher-action@v2 +- uses: gruntwork-io/patcher-action@v3 with: patcher_command: report - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} exclude_dirs: "examples/**,tests/**" working_dir: ./ spec_file: /tmp/patcher-spec.json @@ -171,7 +260,7 @@ If you want to exclude certain directories or files, you can add filtering: Control how aggressively Patcher updates dependencies: ```yml -- uses: gruntwork-io/patcher-action@v2 +- uses: gruntwork-io/patcher-action@v3 with: patcher_command: update update_strategy: next-safe # or "next-breaking" @@ -182,7 +271,7 @@ Control how aggressively Patcher updates dependencies: Test your workflow without creating actual pull requests: ```yml -- uses: gruntwork-io/patcher-action@v2 +- uses: gruntwork-io/patcher-action@v3 with: patcher_command: update dry_run: true From 7ebc501ee781bd830256d53d664d6ad70666ffe6 Mon Sep 17 00:00:00 2001 From: Josh Padnick Date: Wed, 3 Sep 2025 00:26:43 -0700 Subject: [PATCH 05/18] Update Patcher overview to reflect the latest available info. --- docs/2.0/docs/patcher/concepts/index.md | 34 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index cf7ab8275..1ffe719e6 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -1,9 +1,37 @@ # What is Gruntwork Patcher? -Gruntwork Patcher automates the process of keeping your infrastructure code ([Terragrunt](https://terragrunt.gruntwork.io/) and [OpenTofu](https://opentofu.org/)) up to date, including applying patches to ensure compatibility with backward-incompatible module releases. +Gruntwork Patcher automates the process of keeping your infrastructure code ([Terragrunt](https://terragrunt.gruntwork.io/), [OpenTofu](https://opentofu.org/), and [Terraform](https://terraform.io)) up to date, including applying patches to ensure compatibility with backward-incompatible module releases. + +We use the term "Patcher" to refer to the [Patcher CLI](https://github.com/gruntwork-io/patcher-cli), the public [Patcher GitHub Action](https://github.com/gruntwork-io/patcher-action), and the collection of tools (like Terrapatch[https://github.com/gruntwork-io/terrapatch-cli]) that enable Patcher to be useful. + +## Why use Patcher? Manually identifying updates and assessing whether they can be safely applied can consume significant engineering time for each module dependency. Patcher eliminates this inefficiency by streamlining the update process. -You can use Gruntwork Patcher to manage dependencies on the Gruntwork IaC Library, which includes patches for recent breaking changes to Gruntwork modules. Patcher also supports updating dependencies for your own modules or open-source projects, using semantic versioning to identify safe updates and highlight those that need manual review. +Patcher supports keeping any set of OpenTofu/Terraform modules up to date, whether they be your inhouse modules, third-party open source modules, or modules from the [Gruntwork IaC Library](library/concepts/overview). + +Patcher specializes in keeping infrastructure code up to date and currently supports automatic udpates for: + +- OpenTofu modules +- Terraform modules +- Terragrunt units +- Terragrunt stacks + +## Two update modes + +When most teams think about updating their infrastructure mode, there are two core use cases they look to solve: + +1. **Legacy upgrade.** You wish to take a repo or set of files that are significantly out of date and bring them up to date with the latest OpenTofu/Terraform module versions. +2. **Ongoing updates.** You wish to streamline the process of keeping a repo or set of files up to date over time. + +Patcher can help with both of these use cases. + +For legacy upgrades, the Patcher CLI offers an [interactive mode[(guides/update)] where you can browse all modules in the current working directory and below, request available updates, and upgrade modules one at a time. We've found this approach works well with a modest set of updates, however for significantly out of date repos or files or a large number of files, you may wish to consider alternative approaches. + +For ongoing updates, you can use Patcher in conjunction with our published GitHub Action to automatically scan your repo's modules and [open pull requests](guides/ongoing-updates) with updated module versions. Opening one pull request for every update would be cumbersome, so Patcher supports a variety of [grouping modes](/concepts/grouping) that allow you to streamline your workflow. + +## How does Patcher work? + +Patcher handles both non-breaking and breaking changes. For non-breaking changes, for the [Gruntwork Iac Library](library/concepts/overview), Patcher uses a set of pre-generated changelog files to identify the "next safe change," enabling upgrades to automatically bypass "empty" version upgrades where a module is available at a newer version but in fact has had no actual file changes. Upon request, we can work with you to implement these pre-generated changelogs in your organization. -Gruntwork Patcher provides a clear, README-driven workflow for breaking changes without available patches. When Patcher detects breaking changes, it updates the relevant dependency to the version containing those changes and generates a README file in the folder with the updated file. This README outlines the release notes and details the breaking changes. Users must review the README, address any necessary actions, and remove the file before rerunning Patcher. +For breaking changes, Patcher offers a systematic approach to doing code transformations -- we call these "patches" -- so that module consumers can automatically apply breaking changes to their modules. Or if Patcher detects a breaking change but a patch does not exist, Patcher updates the relevant module to the next breaking change and generates a README file in the folder with the updated file that outlines the release notes and details the breaking changes. Users review the README, address any necessary actions, and remove the file before rerunning Patcher. \ No newline at end of file From 8e35e1327e96b7e3dbd5db54c4e80090eab31b1f Mon Sep 17 00:00:00 2001 From: Josh Padnick Date: Wed, 3 Sep 2025 00:27:22 -0700 Subject: [PATCH 06/18] Update description for "ongoing updates." Still needs work, so committing in progress. --- ...ntinuous-updates.md => ongoing-updates.md} | 189 ++++++------------ 1 file changed, 62 insertions(+), 127 deletions(-) rename docs/2.0/docs/patcher/guides/{github-actions-continuous-updates.md => ongoing-updates.md} (64%) diff --git a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md similarity index 64% rename from docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md rename to docs/2.0/docs/patcher/guides/ongoing-updates.md index 1822b8d1d..1230810f3 100644 --- a/docs/2.0/docs/patcher/guides/github-actions-continuous-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -1,16 +1,13 @@ -# GitHub Actions for Continuous Updates +# Ongoing Updates -:::info -This guide covers setting up GitHub Actions to keep your infrastructure code up to date over time. If you need to promote updates across multiple environments (dev → stage → prod), see [Setting up Promotion Workflows](/2.0/docs/patcher/guides/promotion-workflows). -::: +## Overview -**Related content**: -* [Concepts - Patcher Workflows](/2.0/docs/patcher/concepts/promotion-workflows) -* [Architecture - Overview](/2.0/docs/patcher/architecture) +Patcher supports two primary modes of working: -## Overview +1. **Legacy upgrade.** You wish to take a repo or set of files that are significantly out of date and bring them up to date with the latest OpenTofu/Terraform module versions. +2. **Ongoing updates.** You wish to streamline the process of keeping a repo or set of files up to date over time. -Patcher excels at keeping your infrastructure code current by automatically detecting and applying dependency updates. This guide shows you how to set up a GitHub Actions workflow that scans your entire repository for outdated dependencies and creates pull requests to keep everything up to date. +In this guide, we'll use Patcher to help you with the second mode by setting up a GitHub Actions workflow that scans your entire repository for outdated dependencies and automatically creates pull requests to keep everything up to date. This approach is ideal for teams that want to: - Maintain current dependencies across their entire codebase @@ -20,51 +17,15 @@ This approach is ideal for teams that want to: ## Prerequisites ### Infrastructure as Code -Your codebase should be structured as infrastructure as code (IaC) using tools like Terraform, OpenTofu, or Terragrunt. This setup allows Patcher to automate updates across your infrastructure. +Your infrastructure should be defined as code using some combination of OpenTofu, Terragrunt, and/or Terraform. ### GitHub Repository Setup - Your infrastructure code should be in a GitHub repository -- You'll need a GitHub token with appropriate permissions to create pull requests -- For Gruntwork customers, you'll need a `PIPELINES_READ_TOKEN` to access Patcher - -### GitHub Fine-Grained Personal Access Token Setup - -For GitHub Enterprise users, you'll need to create a fine-grained personal access token with specific permissions. Follow these steps: - -1. **Navigate to GitHub Settings** - - Go to your GitHub Enterprise instance - - Click your profile picture → **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens** - -2. **Create New Token** - - Click **Generate new token** - - Select **Fine-grained personal access token** +- Your default `GITHUB_TOKEN` that is automatically created with each GitHub Actions run must have permission to create pull requests on the repo where you'll be running Patcher. +- You'll need to manually create a token (we recommend calling it `PIPELINES_READ_TOKEN`) that has permission to access the Patcher CLI and Terrapatch CLI tools. -3. **Configure Token Settings** - - **Token name**: Choose a descriptive name (e.g., "Patcher CI Token") - - **Expiration**: Set to **90 days** or longer based on your security policy - - **Resource owner**: Select your organization - :::warning - It's easy to not select the right organization! Be sure to select the GitHub org -- not your username -- that actually holds the repos you're looking to access. - ::: - -4. **Repository Access** - Configure access to the following repositories: - - **Your organization's patcher-cli repository** (typically `gruntwork-io/patcher-cli` or your custom org) - - **Your organization's terrapatch-cli repository** (typically `gruntwork-io/terrapatch-cli` or your custom org) - -5. **Set Required Permissions** - Under "Permissions", configure these **Repository permissions**: - - **Contents**: **Read** access - - **Metadata**: **Read** access - - **Actions**: **Read** access (for downloading releases) - -6. **Generate and Store Token** - - Click **Generate token** - - **Copy the token immediately** (you won't be able to see it again) - - Store it securely as a GitHub secret named `PIPELINES_READ_TOKEN` in your repository - -:::warning -Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. +:::info +Patcher CLI is a binary and is agnostic to the underlying CI system, however the GitHub Action we describe here currently only works for GitHub.com or GitHub Enterprise. We'll be adding equivalent support for GitLab soon. ::: ## Implementation @@ -100,11 +61,11 @@ jobs: spec: ${{ steps.get-spec.outputs.spec }} steps: - uses: actions/checkout@v4 - - uses: gruntwork-io/patcher-action@v3 + - uses: gruntwork-io/patcher-action@v2 id: get-spec with: patcher_command: report - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ spec_file: /tmp/patcher-spec.json @@ -117,83 +78,24 @@ jobs: dependency: ${{ fromJson(needs.patcher-report.outputs.spec).Dependencies }} steps: - uses: actions/checkout@v4 + with: + # Make sure Patcher has enough Git history to correctly determine changes + fetch-depth: 0 - name: Create the spec file shell: bash run: | echo '${{ needs.patcher-report.outputs.spec }}' > /tmp/patcher-spec.json - - uses: gruntwork-io/patcher-action@v3 + - uses: gruntwork-io/patcher-action@v2 with: patcher_command: update - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + github_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ dependency: ${{ matrix.dependency.ID }} spec_file: /tmp/patcher-spec.json - pr_title: "[Patcher] Update ${{ matrix.dependency.ID }}" - pr_target_branch: "patcher-updates-${{ matrix.dependency.ID }}" -``` - -## Migrating from v2 to v3 - -:::info -Patcher Action v3 introduces breaking changes that require updating your workflow configuration. This section helps you migrate from v2 to v3. -::: - -### Key Breaking Changes - -**1. Token Consolidation** -- **v2**: Used separate `github_token`, `read_token`, and `update_token` inputs -- **v3**: Uses a single `auth_token` input for all authentication - -**2. Parameter Renames** -- `pull_request_branch` → `pr_target_branch` -- `pull_request_title` → `pr_title` - -**3. New Custom Organization Support** -- `github_org`: Specify custom organization (defaults to "gruntwork-io") -- `github_base_url`: Support for GitHub Enterprise instances -- `patcher_git_repo` / `terrapatch_git_repo`: Custom repository names -- `terrapatch_github_org`: Separate organization for terrapatch - -### Migration Examples - -**Before (v2):** -```yml -- uses: gruntwork-io/patcher-action@v2 - with: - patcher_command: report - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} - working_dir: ./ - spec_file: /tmp/patcher-spec.json - -- uses: gruntwork-io/patcher-action@v2 - with: - patcher_command: update - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} - dependency: ${{ matrix.dependency.ID }} - spec_file: /tmp/patcher-spec.json - pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" - pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" -``` - -**After (v3):** -```yml -- uses: gruntwork-io/patcher-action@v3 - with: - patcher_command: report - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} - working_dir: ./ - spec_file: /tmp/patcher-spec.json - -- uses: gruntwork-io/patcher-action@v3 - with: - patcher_command: update - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} - dependency: ${{ matrix.dependency.ID }} - spec_file: /tmp/patcher-spec.json - pr_title: "[Patcher] Update ${{ matrix.dependency.ID }}" - pr_target_branch: "patcher-updates-${{ matrix.dependency.ID }}" + pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" + pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" ``` ### Custom Organization Setup (v3 Only) @@ -214,15 +116,6 @@ For GitHub Enterprise or custom organizations: spec_file: /tmp/patcher-spec.json ``` -### Migration Checklist - -- [ ] Replace `github_token` with `auth_token` in all patcher-action steps -- [ ] Update `pull_request_branch` to `pr_target_branch` -- [ ] Update `pull_request_title` to `pr_title` -- [ ] Update action version from `@v2` to `@v3` -- [ ] Configure custom organization settings if needed (GitHub Enterprise users) -- [ ] Test the updated workflow with a manual trigger - ## Key Configuration Options ### Scheduling @@ -298,3 +191,45 @@ If you need to promote updates across multiple environments (dev → stage → p 5. **Merge updates**: Review and merge the pull requests to apply updates The workflow will automatically run on your configured schedule, keeping your infrastructure dependencies current with minimal manual intervention. + + + +### GitHub Fine-Grained Personal Access Token Setup + +For GitHub Enterprise users, you'll need to create a fine-grained personal access token with specific permissions. Follow these steps: + +1. **Navigate to GitHub Settings** + - Go to your GitHub Enterprise instance + - Click your profile picture → **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens** + +2. **Create New Token** + - Click **Generate new token** + - Select **Fine-grained personal access token** + +3. **Configure Token Settings** + - **Token name**: Choose a descriptive name (e.g., "Patcher CI Token") + - **Expiration**: Set to **90 days** or longer based on your security policy + - **Resource owner**: Select your organization + :::warning + It's easy to not select the right organization! Be sure to select the GitHub org -- not your username -- that actually holds the repos you're looking to access. + ::: + +4. **Repository Access** + Configure access to the following repositories: + - **Your organization's patcher-cli repository** (typically `gruntwork-io/patcher-cli` or your custom org) + - **Your organization's terrapatch-cli repository** (typically `gruntwork-io/terrapatch-cli` or your custom org) + +5. **Set Required Permissions** + Under "Permissions", configure these **Repository permissions**: + - **Contents**: **Read** access + - **Metadata**: **Read** access + - **Actions**: **Read** access (for downloading releases) + +6. **Generate and Store Token** + - Click **Generate token** + - **Copy the token immediately** (you won't be able to see it again) + - Store it securely as a GitHub secret named `PIPELINES_READ_TOKEN` in your repository + +:::warning +Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. +::: \ No newline at end of file From 76347b1e6eb7bed8e856af6edb2471295b57a58d Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 07:35:32 +0000 Subject: [PATCH 07/18] docs(patcher): align ongoing-updates guide with patcher-action v3 custom-org inputs/outputs and workflow setup Co-Authored-By: Josh Padnick --- .../docs/patcher/guides/ongoing-updates.md | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index 1230810f3..bf1b2d722 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -58,16 +58,15 @@ jobs: patcher-report: runs-on: ubuntu-latest outputs: - spec: ${{ steps.get-spec.outputs.spec }} + dependencies: ${{ steps.get-deps.outputs.dependencies }} steps: - uses: actions/checkout@v4 - - uses: gruntwork-io/patcher-action@v2 - id: get-spec + - id: get-deps + uses: gruntwork-io/patcher-action@v3 with: patcher_command: report - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ - spec_file: /tmp/patcher-spec.json update-dependencies: needs: [patcher-report] @@ -75,27 +74,21 @@ jobs: strategy: fail-fast: false matrix: - dependency: ${{ fromJson(needs.patcher-report.outputs.spec).Dependencies }} + dependency: ${{ fromJson(needs.patcher-report.outputs.dependencies) }} steps: - uses: actions/checkout@v4 with: # Make sure Patcher has enough Git history to correctly determine changes fetch-depth: 0 - - name: Create the spec file - shell: bash - run: | - echo '${{ needs.patcher-report.outputs.spec }}' > /tmp/patcher-spec.json - - - uses: gruntwork-io/patcher-action@v2 + - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update - github_token: ${{ secrets.PIPELINES_READ_TOKEN }} + update_token: ${{ secrets.PIPELINES_READ_TOKEN }} working_dir: ./ - dependency: ${{ matrix.dependency.ID }} - spec_file: /tmp/patcher-spec.json - pull_request_title: "[Patcher] Update ${{ matrix.dependency.ID }}" - pull_request_branch: "patcher-updates-${{ matrix.dependency.ID }}" + dependency: ${{ matrix.dependency }} + pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" + pull_request_branch: "patcher-updates-${{ matrix.dependency }}" ``` ### Custom Organization Setup (v3 Only) @@ -106,14 +99,14 @@ For GitHub Enterprise or custom organizations: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: report - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PIPELINES_READ_TOKEN }} github_base_url: "https://github.company.com" github_org: "my-custom-org" patcher_git_repo: "patcher-cli" terrapatch_git_repo: "terrapatch-cli" - terrapatch_github_org: "my-custom-org" # Optional: defaults to github_org + # Optional: defaults to github_org if not provided + terrapatch_github_org: "my-custom-org" working_dir: ./ - spec_file: /tmp/patcher-spec.json ``` ## Key Configuration Options @@ -146,10 +139,9 @@ If you want to exclude certain directories or files, you can add filtering: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: report - auth_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PIPELINES_READ_TOKEN }} exclude_dirs: "examples/**,tests/**" working_dir: ./ - spec_file: /tmp/patcher-spec.json ``` ### Update Strategies @@ -159,6 +151,7 @@ Control how aggressively Patcher updates dependencies: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update + update_token: ${{ secrets.PIPELINES_READ_TOKEN }} update_strategy: next-safe # or "next-breaking" # ... other parameters ``` @@ -170,6 +163,7 @@ Test your workflow without creating actual pull requests: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update + update_token: ${{ secrets.PIPELINES_READ_TOKEN }} dry_run: true # ... other parameters ``` @@ -232,4 +226,4 @@ For GitHub Enterprise users, you'll need to create a fine-grained personal acces :::warning Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. -::: \ No newline at end of file +::: From 8c6bad7e8d0a654f9af1a5759886d077a2e47bb0 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 07:42:18 +0000 Subject: [PATCH 08/18] docs(patcher): clarify step-by-step setup and authentication for GitHub Action ongoing updates Co-Authored-By: Josh Padnick --- .../docs/patcher/guides/ongoing-updates.md | 125 +++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index bf1b2d722..e90f45a2e 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -34,6 +34,127 @@ The GitHub Actions workflow consists of two main jobs: 1. **`patcher-report`**: Scans your entire repository for outdated dependencies 2. **`update-dependencies`**: Creates individual pull requests for each dependency that needs updating +### Step-by-step setup +### Step-by-step setup + +1) Configure repository permissions +- Ensure the workflow has permissions: + permissions: + contents: write + pull-requests: write + +2) Create a fine-grained token +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). +- Save it as a repository secret named PIPELINES_READ_TOKEN. + +3) Choose when to run +- Schedule (recommended): weekly or at a cadence that fits your change velocity. +- Manual: use workflow_dispatch for ad-hoc runs. +- repository_dispatch: trigger when a new module release is published (optional). + +4) Add the workflow file +- Create .github/workflows/patcher-continuous-updates.yml using the example below. +- The workflow has two jobs: + - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). + - update-dependencies: iterates those dependencies and opens one PR per dependency. + +5) Confirm branch protections +- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). + +6) Run and review +- Manually run the workflow the first time to validate configuration. +- Review the generated PRs and merge as desired. + +### Step-by-step setup + +1) Configure repository permissions +- Ensure the workflow has permissions: + permissions: + contents: write + pull-requests: write + +2) Create a fine-grained token +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). +- Save it as a repository secret named PIPELINES_READ_TOKEN. + +3) Choose when to run +- Schedule (recommended): weekly or at a cadence that fits your change velocity. +- Manual: use workflow_dispatch for ad-hoc runs. +- repository_dispatch: trigger when a new module release is published (optional). + +4) Add the workflow file +- Create .github/workflows/patcher-continuous-updates.yml using the example below. +- The workflow has two jobs: + - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). + - update-dependencies: iterates those dependencies and opens one PR per dependency. + +5) Confirm branch protections +- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). + +6) Run and review +- Manually run the workflow the first time to validate configuration. +- Review the generated PRs and merge as desired. + + +1) Configure repository permissions +- Ensure the workflow has permissions: + permissions: + contents: write + pull-requests: write + +2) Create a fine-grained token +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). +- Save it as a repository secret named PIPELINES_READ_TOKEN. + +3) Choose when to run +- Schedule (recommended): weekly or at a cadence that fits your change velocity. +- Manual: use workflow_dispatch for ad-hoc runs. +- repository_dispatch: trigger when a new module release is published (optional). + +4) Add the workflow file +- Create .github/workflows/patcher-continuous-updates.yml using the example below. +- The workflow has two jobs: + - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). + - update-dependencies: iterates those dependencies and opens one PR per dependency. + +5) Confirm branch protections +- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). + +6) Run and review +- Manually run the workflow the first time to validate configuration. +- Review the generated PRs and merge as desired. + +### Step-by-step setup + +1) Configure repository permissions +- Ensure the workflow has permissions: + permissions: + contents: write + pull-requests: write + +2) Create a fine-grained token +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). +- Save it as a repository secret named PIPELINES_READ_TOKEN. + +3) Choose when to run +- Schedule (recommended): weekly or at a cadence that fits your change velocity. +- Manual: use workflow_dispatch for ad-hoc runs. +- repository_dispatch: trigger when a new module release is published (optional). + +4) Add the workflow file +- Create .github/workflows/patcher-continuous-updates.yml using the example below. +- The workflow has two jobs: + - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). + - update-dependencies: iterates those dependencies and opens one PR per dependency. + +5) Confirm branch protections +- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). + +6) Run and review +- Manually run the workflow the first time to validate configuration. +- Review the generated PRs and merge as desired. + + ### Basic Workflow Setup @@ -118,8 +239,8 @@ The workflow is configured to run: - **Scheduled**: Every Monday at 04:15 UTC (customize as needed) ### Authentication -- `PIPELINES_READ_TOKEN`: Required for Gruntwork customers to access Patcher and download dependencies -- The token needs `contents: write` and `pull-requests: write` permissions +- PIPELINES_READ_TOKEN: Fine-grained PAT that can read releases of patcher-cli and terrapatch-cli in your organization; store as a repository secret. +- Use read_token for the report job and update_token for the update job. If unset, both fall back to github_token, but we recommend a dedicated PAT for reliability. ### Working Directory - `working_dir: ./` scans the entire repository From 2684728b21580009a1ed28a0cf430feb645ebeaa Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 07:48:06 +0000 Subject: [PATCH 09/18] docs(patcher): dedupe and keep a single step-by-step setup section Co-Authored-By: Josh Padnick --- .../docs/patcher/guides/ongoing-updates.md | 59 ------------------- 1 file changed, 59 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index e90f45a2e..7bf3fef94 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -35,7 +35,6 @@ The GitHub Actions workflow consists of two main jobs: 1. **`patcher-report`**: Scans your entire repository for outdated dependencies 2. **`update-dependencies`**: Creates individual pull requests for each dependency that needs updating ### Step-by-step setup -### Step-by-step setup 1) Configure repository permissions - Ensure the workflow has permissions: @@ -65,35 +64,6 @@ The GitHub Actions workflow consists of two main jobs: - Manually run the workflow the first time to validate configuration. - Review the generated PRs and merge as desired. -### Step-by-step setup - -1) Configure repository permissions -- Ensure the workflow has permissions: - permissions: - contents: write - pull-requests: write - -2) Create a fine-grained token -- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). -- Save it as a repository secret named PIPELINES_READ_TOKEN. - -3) Choose when to run -- Schedule (recommended): weekly or at a cadence that fits your change velocity. -- Manual: use workflow_dispatch for ad-hoc runs. -- repository_dispatch: trigger when a new module release is published (optional). - -4) Add the workflow file -- Create .github/workflows/patcher-continuous-updates.yml using the example below. -- The workflow has two jobs: - - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). - - update-dependencies: iterates those dependencies and opens one PR per dependency. - -5) Confirm branch protections -- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). - -6) Run and review -- Manually run the workflow the first time to validate configuration. -- Review the generated PRs and merge as desired. 1) Configure repository permissions @@ -124,35 +94,6 @@ The GitHub Actions workflow consists of two main jobs: - Manually run the workflow the first time to validate configuration. - Review the generated PRs and merge as desired. -### Step-by-step setup - -1) Configure repository permissions -- Ensure the workflow has permissions: - permissions: - contents: write - pull-requests: write - -2) Create a fine-grained token -- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). -- Save it as a repository secret named PIPELINES_READ_TOKEN. - -3) Choose when to run -- Schedule (recommended): weekly or at a cadence that fits your change velocity. -- Manual: use workflow_dispatch for ad-hoc runs. -- repository_dispatch: trigger when a new module release is published (optional). - -4) Add the workflow file -- Create .github/workflows/patcher-continuous-updates.yml using the example below. -- The workflow has two jobs: - - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). - - update-dependencies: iterates those dependencies and opens one PR per dependency. - -5) Confirm branch protections -- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). - -6) Run and review -- Manually run the workflow the first time to validate configuration. -- Review the generated PRs and merge as desired. From c35163adfc94355a2d844b0c09d009059068c2a5 Mon Sep 17 00:00:00 2001 From: Josh Padnick Date: Wed, 3 Sep 2025 02:29:21 -0700 Subject: [PATCH 10/18] Lots of updates to the Patcher self-hosting docs, walking through every step. --- .../docs/patcher/guides/ongoing-updates.md | 303 +++++++++--------- sidebars/docs.js | 4 +- 2 files changed, 154 insertions(+), 153 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index 7bf3fef94..4d30590c3 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -2,107 +2,111 @@ ## Overview -Patcher supports two primary modes of working: +As we mentioned in the [Patcher overview](../concepts/index.md), Patcher supports two primary modes of working: 1. **Legacy upgrade.** You wish to take a repo or set of files that are significantly out of date and bring them up to date with the latest OpenTofu/Terraform module versions. 2. **Ongoing updates.** You wish to streamline the process of keeping a repo or set of files up to date over time. -In this guide, we'll use Patcher to help you with the second mode by setting up a GitHub Actions workflow that scans your entire repository for outdated dependencies and automatically creates pull requests to keep everything up to date. +In this guide, we'll use Patcher to help you with the second mode. The basic idea is that we'll set up a GitHub Action that scans your entire repository for outdated dependencies and automatically creates pull requests to keep everything up to date. This approach is ideal for teams that want to: - Maintain current dependencies across their entire codebase - Receive regular automated updates without manual intervention - Keep security vulnerabilities and technical debt to a minimum -## Prerequisites +## Which CI systems are supported? -### Infrastructure as Code -Your infrastructure should be defined as code using some combination of OpenTofu, Terragrunt, and/or Terraform. - -### GitHub Repository Setup -- Your infrastructure code should be in a GitHub repository -- Your default `GITHUB_TOKEN` that is automatically created with each GitHub Actions run must have permission to create pull requests on the repo where you'll be running Patcher. -- You'll need to manually create a token (we recommend calling it `PIPELINES_READ_TOKEN`) that has permission to access the Patcher CLI and Terrapatch CLI tools. +Patcher CLI is a binary and is therefore agnostic to the underlying CI system, however the GitHub Action we describe here currently only works for GitHub.com or GitHub Enterprise. :::info -Patcher CLI is a binary and is agnostic to the underlying CI system, however the GitHub Action we describe here currently only works for GitHub.com or GitHub Enterprise. We'll be adding equivalent support for GitLab soon. +We'll be adding equivalent support for GitLab soon. In the meantime, for non-GitHub users, feel free to adapt the code at https://github.com/gruntwork-io/patcher-action to suit your needs. ::: ## Implementation -The GitHub Actions workflow consists of two main jobs: +We're about to create a GitHub Actions workflow that consists of two main jobs: 1. **`patcher-report`**: Scans your entire repository for outdated dependencies -2. **`update-dependencies`**: Creates individual pull requests for each dependency that needs updating -### Step-by-step setup - -1) Configure repository permissions -- Ensure the workflow has permissions: - permissions: - contents: write - pull-requests: write - -2) Create a fine-grained token -- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). -- Save it as a repository secret named PIPELINES_READ_TOKEN. - -3) Choose when to run -- Schedule (recommended): weekly or at a cadence that fits your change velocity. -- Manual: use workflow_dispatch for ad-hoc runs. -- repository_dispatch: trigger when a new module release is published (optional). - -4) Add the workflow file -- Create .github/workflows/patcher-continuous-updates.yml using the example below. -- The workflow has two jobs: - - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). - - update-dependencies: iterates those dependencies and opens one PR per dependency. - -5) Confirm branch protections -- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). - -6) Run and review -- Manually run the workflow the first time to validate configuration. -- Review the generated PRs and merge as desired. +2. **`patcher-update`**: Creates individual pull requests for each dependency that needs updating +:::info +Individual pull requests can quickly get overwhelming. Once you've got this working, check out our page on [grouping](../concepts/grouping.md) to see how to consolidate many updates into a single pull request. +::: +### Step-by-step setup for GitHub.com users -1) Configure repository permissions -- Ensure the workflow has permissions: - permissions: - contents: write - pull-requests: write +#### 1. Create a GitHub token +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see [GitHub Personal Access Token Setup](#github-personal-access-token-setup) below). +- Save it as a GitHub Actions secret named `PATCHER_CI_TOKEN`. -2) Create a fine-grained token -- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see “GitHub Fine-Grained Personal Access Token Setup” below). -- Save it as a repository secret named PIPELINES_READ_TOKEN. +:::warn +Most of the time when users have challenges getting Patcher to work, it's because their GitHub token is not set up correctly. Be sure to follow these steps carefully, but if you'd like to validate that your GitHub token is configured correctly, consider copying and pasting our [Validate GitHub Access Token](https://github.com/gruntwork-io/patcher-action/blob/main/.github/workflows/validate-github-access.yml) workflow. +::: -3) Choose when to run -- Schedule (recommended): weekly or at a cadence that fits your change velocity. -- Manual: use workflow_dispatch for ad-hoc runs. -- repository_dispatch: trigger when a new module release is published (optional). +#### 2. Add the GitHub Actions workflow file +- In the repo in which you want Patcher to run, create a new file `.github/workflows/patcher-updates.yml`. +- Populate it using one of the [GitHub Actions Workflow Examples](#github-actions-workflow-examples) below. -4) Add the workflow file -- Create .github/workflows/patcher-continuous-updates.yml using the example below. -- The workflow has two jobs: - - patcher-report: discovers outdated dependencies and outputs them as JSON (dependencies). - - update-dependencies: iterates those dependencies and opens one PR per dependency. +#### 3. Choose when to run Patcher +- There are three non-mutually exclusive options for when Patcher will run: + 1. Schedule (recommended): Run Patcher on a weekly basis (or other cadence that fits your workflow). + 2. Manual: Use `workflow_dispatch` for ad-hoc runs. TODO: Clarify what this means and why it's useful. + 3. New module release: Use the `repository_dispatch` trigger to run when a new module release is published. -5) Confirm branch protections -- Ensure the workflow can push branches and open PRs on your target repo (branch protection may require status checks). + TODO: Give examples of how to configure this, or generally more detail so users know what to do here. If the example below already has a schedule, just reference that. -6) Run and review -- Manually run the workflow the first time to validate configuration. +:::info +Almost all customers opt for the scheduled approach, with a periodic manual run. +::: + +#### 4. Run and review! +- Manually run the GitHub Actions workflow the first time to validate configuration. - Review the generated PRs and merge as desired. +TODO: Give users more guidance on how to manually run the GitHub Actions workflow. + +### Step-by-step setup for GitHub Enterprise users + +Many GitHub Enterprise users self-host GitHub Enterprise and wish to host all binaries internally. If you'd like to fully self-host Patcher, then you'll eventually follow the same steps as above in [Step-by-step setup for GitHub.com users](#step-by-step-setup-for-githubcom-users), however first we need to copy over some assets from Gruntwork to your environment. + +#### 1. Self-host the relevant Gruntwork repos + +The first step is to [self-host the IaC Library](../../library/guides/self-hosting.md). Even if you don't use the Gruntwork IaC Library for its modules, we can use the [repo-copier](https://github.com/gruntwork-io/repo-copier) tool in the linked page to copy private repos to any VCS system of your choice. + +To run Patcher locally, you'll need to configure repo-copier to mirror each of the following repos: + +1. https://github.com/gruntwork-io/patcher-cli +2. https://github.com/gruntwork-io/terragrunt-cli +3. https://github.com/gruntwork-io/patcher-action + +#### 2. Follow the steps above + +Follow the steps above in [Step-by-step setup for GitHub.com users](#step-by-step-setup-for-githubcom-users), but don't start testing things (step 4 above), until we've made the modifications below. + +#### 3. Specify your GitHub Enterprise settings + +Update the GitHub Action workflow as described in [For GitHub Enterprise Users](#for-github-enterprise-users) to work with your specific GitHub Enterprise setup. This will: + +- Specify your GitHub Enterprise settings +- Use your local copy of our Patcher GitHub Action (versus our version hosted at GitHub.com); remember that thanks to repo-copier, they should be exactly the same, except that yours is hosted internally. + +#### 4. Make sure your runners will work with the `patcher-action`. + +Our published `patcher-action` specifies the GitHub Actions workflow will `runs-on: ubuntu-latest`. In the GitHub Enterprise environment, this exact runner tag *might* be available for you, but if it's not, you'll either need to: + +1. Change the GitHub Actions workflow `runs-on:` value to a runner you have internaly, or +2. Tag your existing runners with `ubuntu-latest` so it gets picked up by the new GitHub Action. +## GitHub Actions Workflow Examples +We've included example GitHub Actions workflow files both for GitHub.com users and GitHub Enterprise users (both hosted and self-hosted). -### Basic Workflow Setup +### For GitHub.com users -Create a new file `.github/workflows/patcher-continuous-updates.yml` in your repository: +Create a new file `.github/workflows/patcher-updates.yml` in your repository: ```yml -name: Patcher Continuous Updates +name: Patcher Updates on: workflow_dispatch: @@ -124,13 +128,13 @@ jobs: steps: - uses: actions/checkout@v4 - id: get-deps - uses: gruntwork-io/patcher-action@v3 + uses: gruntwork-io/patcher-action@v2 with: patcher_command: report - read_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PATCHER_CI_TOKEN }} working_dir: ./ - update-dependencies: + patcher-update: needs: [patcher-report] runs-on: ubuntu-latest strategy: @@ -142,57 +146,106 @@ jobs: with: # Make sure Patcher has enough Git history to correctly determine changes fetch-depth: 0 - - - uses: gruntwork-io/patcher-action@v3 + + - uses: gruntwork-io/patcher-action@v2 with: patcher_command: update - update_token: ${{ secrets.PIPELINES_READ_TOKEN }} + update_token: ${{ secrets.PATCHER_CI_TOKEN }} working_dir: ./ dependency: ${{ matrix.dependency }} pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" pull_request_branch: "patcher-updates-${{ matrix.dependency }}" ``` -### Custom Organization Setup (v3 Only) +### For GitHub Enterprise Users + +Use the same GitHub Action above, but replace each of the `uses: gruntwork-io/patcher-action@v2` as follows: -For GitHub Enterprise or custom organizations: +TODO: Double-check this; is this the right way to do this? ```yml -- uses: gruntwork-io/patcher-action@v3 +# TODO: Make it clear where this gets swapped in +# TODO: Make it clear the user should specify their own copy of gruntwork-io/patcher-action, not ours. +- uses: gruntwork-io/patcher-action@v2 with: patcher_command: report - read_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PATCHER_CI_TOKEN }} github_base_url: "https://github.company.com" github_org: "my-custom-org" patcher_git_repo: "patcher-cli" terrapatch_git_repo: "terrapatch-cli" - # Optional: defaults to github_org if not provided - terrapatch_github_org: "my-custom-org" working_dir: ./ + +... + + # TODO: udpate these values to be correct for GitHUb Enterprise + - uses: gruntwork-io/patcher-action@v2 + with: + patcher_command: update + update_token: ${{ secrets.PATCHER_CI_TOKEN }} + working_dir: ./ + dependency: ${{ matrix.dependency }} + pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" + pull_request_branch: "patcher-updates-${{ matrix.dependency }}" + ``` -## Key Configuration Options +## GitHub Personal Access Token Setup -### Scheduling -The workflow is configured to run: -- **Manually**: Using `workflow_dispatch` for testing -- **On new releases**: Via `repository_dispatch` when Gruntwork releases new modules -- **Scheduled**: Every Monday at 04:15 UTC (customize as needed) +You'll need to manually create a GitHub token that has permission to access the Patcher CLI and Terrapatch CLI tools. -### Authentication -- PIPELINES_READ_TOKEN: Fine-grained PAT that can read releases of patcher-cli and terrapatch-cli in your organization; store as a repository secret. -- Use read_token for the report job and update_token for the update job. If unset, both fall back to github_token, but we recommend a dedicated PAT for reliability. +You could create either a [fine-grained or classic token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#types-of-personal-access-tokens), and we recommend creating a fine-grained token as follows: -### Working Directory -- `working_dir: ./` scans the entire repository -- You can specify a subdirectory if your infrastructure code is in a specific folder +#### 1. Navigate to GitHub Settings + - Click your profile picture → **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens** -### Pull Request Strategy -- Creates one pull request per dependency -- Uses descriptive branch names: `patcher-updates-{dependency-id}` -- Includes clear titles indicating which dependency is being updated +#### 2. Create New Token + - Click **Generate new token** + - Select **Fine-grained personal access token** -## Customization Options +#### 3. Configure Token Settings + - **Token name**: Choose a descriptive name (e.g., `PATCHER_CI_TOKEN`) + - **Expiration**: Set to **90 days** or longer based on your security policy + - **Resource owner**: Select the GitHub organization that holds the patcher-cli and terrapatch-cli tools. + - If you are accessing these via GitHub.com, the organization is `gruntwork-io`. + - If you are accessing these via self-hosted GitHub Enterprise, the organization is whatever GitHub organization has the `patcher-cli` and `terrapatch-cli` repos. + + :::warning + It's easy to not select the right organization! Be sure to select the right GitHub org -- not your username -- that actually holds the repos you're looking to access. + ::: + +#### 4. Configure Repository Access + Configure access to the following repositories: + - The **patcher-cli repository** (typically `gruntwork-io/patcher-cli` or your custom org) + - The **terrapatch-cli repository** (typically `gruntwork-io/terrapatch-cli` or your custom org) + +#### 5. Set Required Permissions + Under "Permissions", configure these **Repository permissions**: + - **Contents**: **Read** access + - **Metadata**: **Read** access + - **Actions**: **Read** access (for downloading releases) + + :::info + The GitHub Action will also need the permission to open pull requests, however it will get that from the `GITHUB_TOKEN` that is automatically generated for each GitHub Actions workflow run. Therefore this token can be read-only. + ::: + +#### 6. Generate and Store Token + - Click **Generate token** + - **Copy the token immediately** (you won't be able to see it again) + - Store it securely as a GitHub secret named `PATCHER_CI_TOKEN` in your repository + TODO: Give more guidance on where to store this. + + :::warning + Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. + ::: + +Your `PATCHER_CI_TOKEN` token is now ready for use! + +## Key Configuration Options + +For more information on the configuration options in our standard GitHub Action, see the README at https://github.com/gruntwork-io/patcher-action. + +### Customization Options ### Filtering Dependencies If you want to exclude certain directories or files, you can add filtering: @@ -201,7 +254,7 @@ If you want to exclude certain directories or files, you can add filtering: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: report - read_token: ${{ secrets.PIPELINES_READ_TOKEN }} + read_token: ${{ secrets.PATCHER_CI_TOKEN }} exclude_dirs: "examples/**,tests/**" working_dir: ./ ``` @@ -213,7 +266,7 @@ Control how aggressively Patcher updates dependencies: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update - update_token: ${{ secrets.PIPELINES_READ_TOKEN }} + update_token: ${{ secrets.PATCHER_CI_TOKEN }} update_strategy: next-safe # or "next-breaking" # ... other parameters ``` @@ -225,7 +278,7 @@ Test your workflow without creating actual pull requests: - uses: gruntwork-io/patcher-action@v3 with: patcher_command: update - update_token: ${{ secrets.PIPELINES_READ_TOKEN }} + update_token: ${{ secrets.PATCHER_CI_TOKEN }} dry_run: true # ... other parameters ``` @@ -236,56 +289,4 @@ If you need to promote updates across multiple environments (dev → stage → p - Environment-specific scanning and updates - Controlled promotion between environments -- Validation gates between each environment - -## Next Steps - -1. **Set up the workflow**: Add the YAML file to your repository -2. **Configure secrets**: Add your `PIPELINES_READ_TOKEN` to GitHub secrets -3. **Test manually**: Use the "Run workflow" button to test the setup -4. **Review pull requests**: Patcher will create PRs for each outdated dependency -5. **Merge updates**: Review and merge the pull requests to apply updates - -The workflow will automatically run on your configured schedule, keeping your infrastructure dependencies current with minimal manual intervention. - - - -### GitHub Fine-Grained Personal Access Token Setup - -For GitHub Enterprise users, you'll need to create a fine-grained personal access token with specific permissions. Follow these steps: - -1. **Navigate to GitHub Settings** - - Go to your GitHub Enterprise instance - - Click your profile picture → **Settings** → **Developer settings** → **Personal access tokens** → **Fine-grained tokens** - -2. **Create New Token** - - Click **Generate new token** - - Select **Fine-grained personal access token** - -3. **Configure Token Settings** - - **Token name**: Choose a descriptive name (e.g., "Patcher CI Token") - - **Expiration**: Set to **90 days** or longer based on your security policy - - **Resource owner**: Select your organization - :::warning - It's easy to not select the right organization! Be sure to select the GitHub org -- not your username -- that actually holds the repos you're looking to access. - ::: - -4. **Repository Access** - Configure access to the following repositories: - - **Your organization's patcher-cli repository** (typically `gruntwork-io/patcher-cli` or your custom org) - - **Your organization's terrapatch-cli repository** (typically `gruntwork-io/terrapatch-cli` or your custom org) - -5. **Set Required Permissions** - Under "Permissions", configure these **Repository permissions**: - - **Contents**: **Read** access - - **Metadata**: **Read** access - - **Actions**: **Read** access (for downloading releases) - -6. **Generate and Store Token** - - Click **Generate token** - - **Copy the token immediately** (you won't be able to see it again) - - Store it securely as a GitHub secret named `PIPELINES_READ_TOKEN` in your repository - -:::warning -Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. -::: +- Validation gates between each environment \ No newline at end of file diff --git a/sidebars/docs.js b/sidebars/docs.js index 20c4fb406..5b0579fd2 100644 --- a/sidebars/docs.js +++ b/sidebars/docs.js @@ -572,9 +572,9 @@ const sidebar = [ collapsed: true, items: [ { - label: "GitHub Actions for Continuous Updates", + label: "Ongoing Updates", type: "doc", - id: "2.0/docs/patcher/guides/github-actions-continuous-updates", + id: "2.0/docs/patcher/guides/ongoing-updates", }, { label: "Setting up Promotion Workflows", From 5385c3d0ddea2d75e07405eb0f6177377f3a9b68 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:13:38 +0000 Subject: [PATCH 11/18] docs(patcher): resolve TODOs, clarify enterprise two-job workflow, standardize :::warn, keep @v2 Co-Authored-By: Josh Padnick --- .../docs/patcher/guides/ongoing-updates.md | 84 +++++++++++-------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index 4d30590c3..220a2ec75 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -50,10 +50,10 @@ Most of the time when users have challenges getting Patcher to work, it's becaus #### 3. Choose when to run Patcher - There are three non-mutually exclusive options for when Patcher will run: 1. Schedule (recommended): Run Patcher on a weekly basis (or other cadence that fits your workflow). - 2. Manual: Use `workflow_dispatch` for ad-hoc runs. TODO: Clarify what this means and why it's useful. + 2. Manual: Use `workflow_dispatch` for ad-hoc runs. This lets you trigger Patcher on demand from the GitHub UI to test changes, validate permissions, or run outside your normal schedule. 3. New module release: Use the `repository_dispatch` trigger to run when a new module release is published. - TODO: Give examples of how to configure this, or generally more detail so users know what to do here. If the example below already has a schedule, just reference that. + See the examples below for a scheduled run and a repository_dispatch trigger you can reuse. For most teams, a weekly schedule plus the ability to run manually works well. :::info Almost all customers opt for the scheduled approach, with a periodic manual run. @@ -63,7 +63,7 @@ Almost all customers opt for the scheduled approach, with a periodic manual run. - Manually run the GitHub Actions workflow the first time to validate configuration. - Review the generated PRs and merge as desired. -TODO: Give users more guidance on how to manually run the GitHub Actions workflow. +To run manually: in your repo, go to Actions → select “Patcher Updates” → Run workflow → choose the branch → Run workflow. ### Step-by-step setup for GitHub Enterprise users @@ -76,7 +76,7 @@ The first step is to [self-host the IaC Library](../../library/guides/self-hosti To run Patcher locally, you'll need to configure repo-copier to mirror each of the following repos: 1. https://github.com/gruntwork-io/patcher-cli -2. https://github.com/gruntwork-io/terragrunt-cli +2. https://github.com/gruntwork-io/terrapatch-cli 3. https://github.com/gruntwork-io/patcher-action #### 2. Follow the steps above @@ -146,7 +146,7 @@ jobs: with: # Make sure Patcher has enough Git history to correctly determine changes fetch-depth: 0 - + - uses: gruntwork-io/patcher-action@v2 with: patcher_command: update @@ -156,30 +156,48 @@ jobs: pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" pull_request_branch: "patcher-updates-${{ matrix.dependency }}" ``` +### For GitHub Enterprise users -### For GitHub Enterprise Users - -Use the same GitHub Action above, but replace each of the `uses: gruntwork-io/patcher-action@v2` as follows: +Use the same GitHub Action above, but configure two jobs within the same workflow and point to your GitHub Enterprise instance and organization via the enterprise inputs. If you mirror the action internally, replace the action reference to your mirrored copy. -TODO: Double-check this; is this the right way to do this? +Here is an example showing two jobs in a single workflow: ```yml -# TODO: Make it clear where this gets swapped in -# TODO: Make it clear the user should specify their own copy of gruntwork-io/patcher-action, not ours. -- uses: gruntwork-io/patcher-action@v2 - with: - patcher_command: report - read_token: ${{ secrets.PATCHER_CI_TOKEN }} - github_base_url: "https://github.company.com" - github_org: "my-custom-org" - patcher_git_repo: "patcher-cli" - terrapatch_git_repo: "terrapatch-cli" - working_dir: ./ - -... +jobs: + # 1) Report job (Enterprise): discover outdated dependencies + patcher-report: + runs-on: ubuntu-latest + outputs: + dependencies: ${{ steps.get-deps.outputs.dependencies }} + steps: + - uses: actions/checkout@v4 + - id: get-deps + uses: my-enterprise-org/patcher-action@v2 + with: + patcher_command: report + read_token: ${{ secrets.PATCHER_CI_TOKEN }} + github_base_url: "https://github.company.com" + github_org: "my-enterprise-org" + patcher_git_repo: "patcher-cli" + terrapatch_git_repo: "terrapatch-cli" + # Optional: defaults to github_org if not provided + terrapatch_github_org: "my-enterprise-org" + working_dir: ./ - # TODO: udpate these values to be correct for GitHUb Enterprise - - uses: gruntwork-io/patcher-action@v2 + # 2) Update job (Enterprise): open one PR per dependency + patcher-update: + needs: [patcher-report] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + dependency: ${{ fromJson(needs.patcher-report.outputs.dependencies) }} + steps: + - uses: actions/checkout@v4 + with: + # Ensure enough history for accurate diffs + fetch-depth: 0 + - uses: gruntwork-io/patcher-action@v2 with: patcher_command: update update_token: ${{ secrets.PATCHER_CI_TOKEN }} @@ -187,7 +205,6 @@ TODO: Double-check this; is this the right way to do this? dependency: ${{ matrix.dependency }} pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" pull_request_branch: "patcher-updates-${{ matrix.dependency }}" - ``` ## GitHub Personal Access Token Setup @@ -210,7 +227,7 @@ You could create either a [fine-grained or classic token](https://docs.github.co - If you are accessing these via GitHub.com, the organization is `gruntwork-io`. - If you are accessing these via self-hosted GitHub Enterprise, the organization is whatever GitHub organization has the `patcher-cli` and `terrapatch-cli` repos. - :::warning + :::warn It's easy to not select the right organization! Be sure to select the right GitHub org -- not your username -- that actually holds the repos you're looking to access. ::: @@ -222,7 +239,7 @@ You could create either a [fine-grained or classic token](https://docs.github.co #### 5. Set Required Permissions Under "Permissions", configure these **Repository permissions**: - **Contents**: **Read** access - - **Metadata**: **Read** access + - **Metadata**: **Read** access - **Actions**: **Read** access (for downloading releases) :::info @@ -232,10 +249,9 @@ You could create either a [fine-grained or classic token](https://docs.github.co #### 6. Generate and Store Token - Click **Generate token** - **Copy the token immediately** (you won't be able to see it again) - - Store it securely as a GitHub secret named `PATCHER_CI_TOKEN` in your repository - TODO: Give more guidance on where to store this. + - Store it as a GitHub Actions secret named `PATCHER_CI_TOKEN` in the repository where the workflow runs. - :::warning + :::warn Keep your token secure and never commit it to your repository. Always store it as a GitHub secret. ::: @@ -251,7 +267,7 @@ For more information on the configuration options in our standard GitHub Action, If you want to exclude certain directories or files, you can add filtering: ```yml -- uses: gruntwork-io/patcher-action@v3 +- uses: gruntwork-io/patcher-action@v2 with: patcher_command: report read_token: ${{ secrets.PATCHER_CI_TOKEN }} @@ -263,7 +279,7 @@ If you want to exclude certain directories or files, you can add filtering: Control how aggressively Patcher updates dependencies: ```yml -- uses: gruntwork-io/patcher-action@v3 +- uses: gruntwork-io/patcher-action@v2 with: patcher_command: update update_token: ${{ secrets.PATCHER_CI_TOKEN }} @@ -275,7 +291,7 @@ Control how aggressively Patcher updates dependencies: Test your workflow without creating actual pull requests: ```yml -- uses: gruntwork-io/patcher-action@v3 +- uses: gruntwork-io/patcher-action@v2 with: patcher_command: update update_token: ${{ secrets.PATCHER_CI_TOKEN }} @@ -289,4 +305,4 @@ If you need to promote updates across multiple environments (dev → stage → p - Environment-specific scanning and updates - Controlled promotion between environments -- Validation gates between each environment \ No newline at end of file +- Validation gates between each environment From 05dc55a54516533b9f786164c5a6a1d87dfbf44c Mon Sep 17 00:00:00 2001 From: Josh Padnick Date: Wed, 3 Sep 2025 18:46:42 -0700 Subject: [PATCH 12/18] Add small note to docs. --- docs/2.0/docs/patcher/guides/ongoing-updates.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index 220a2ec75..b7aea45eb 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -97,6 +97,10 @@ Our published `patcher-action` specifies the GitHub Actions workflow will `runs- 1. Change the GitHub Actions workflow `runs-on:` value to a runner you have internaly, or 2. Tag your existing runners with `ubuntu-latest` so it gets picked up by the new GitHub Action. +#### 5. Make your internal GitHub Action accessible + +By default, repos in GitHub Enterprise are not accessible to GitHub Actions run in other repos. We will need to change this setting by going to your internal `patcher-action` rep → click Settings → click Actions, then General → scroll down to "Access" and select the desired access level (we recommend "Accessible from repositories in the 'your_org' organization"). + ## GitHub Actions Workflow Examples We've included example GitHub Actions workflow files both for GitHub.com users and GitHub Enterprise users (both hosted and self-hosted). From 3a8dbbfee0c495a3c4718322ca97bc23bae506d3 Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 12:59:55 -0400 Subject: [PATCH 13/18] Update docs/2.0/docs/patcher/concepts/index.md --- docs/2.0/docs/patcher/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index 1ffe719e6..72046b838 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -8,7 +8,7 @@ We use the term "Patcher" to refer to the [Patcher CLI](https://github.com/grunt Manually identifying updates and assessing whether they can be safely applied can consume significant engineering time for each module dependency. Patcher eliminates this inefficiency by streamlining the update process. -Patcher supports keeping any set of OpenTofu/Terraform modules up to date, whether they be your inhouse modules, third-party open source modules, or modules from the [Gruntwork IaC Library](library/concepts/overview). +Patcher supports keeping any set of OpenTofu/Terraform modules up to date, whether they be your inhouse modules, third-party open source modules, or modules from the [Gruntwork IaC Library](library/concepts/overview). Patcher specializes in keeping infrastructure code up to date and currently supports automatic udpates for: From 45fbe752f364e186ce72b7ac09abbca40e88ae68 Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:00:03 -0400 Subject: [PATCH 14/18] Update docs/2.0/docs/patcher/concepts/index.md --- docs/2.0/docs/patcher/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index 72046b838..a00bc18d5 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -10,7 +10,7 @@ Manually identifying updates and assessing whether they can be safely applied ca Patcher supports keeping any set of OpenTofu/Terraform modules up to date, whether they be your inhouse modules, third-party open source modules, or modules from the [Gruntwork IaC Library](library/concepts/overview). -Patcher specializes in keeping infrastructure code up to date and currently supports automatic udpates for: +Patcher specializes in keeping infrastructure code up to date and currently supports automatic updates for: - OpenTofu modules - Terraform modules From 84241b6a3e43946d5135cb63adc71e084c162f37 Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:00:09 -0400 Subject: [PATCH 15/18] Update docs/2.0/docs/patcher/concepts/index.md --- docs/2.0/docs/patcher/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index a00bc18d5..bc9aa53fc 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -19,7 +19,7 @@ Patcher specializes in keeping infrastructure code up to date and currently supp ## Two update modes -When most teams think about updating their infrastructure mode, there are two core use cases they look to solve: +When most teams think about updating their infrastructure code, there are two core use cases they look to solve: 1. **Legacy upgrade.** You wish to take a repo or set of files that are significantly out of date and bring them up to date with the latest OpenTofu/Terraform module versions. 2. **Ongoing updates.** You wish to streamline the process of keeping a repo or set of files up to date over time. From 7c6f1fbd31ffe90154a9a560aa88d67b99061ce6 Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:00:31 -0400 Subject: [PATCH 16/18] Update docs/2.0/docs/patcher/concepts/index.md --- docs/2.0/docs/patcher/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index bc9aa53fc..238e9ee67 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -26,7 +26,7 @@ When most teams think about updating their infrastructure code, there are two co Patcher can help with both of these use cases. -For legacy upgrades, the Patcher CLI offers an [interactive mode[(guides/update)] where you can browse all modules in the current working directory and below, request available updates, and upgrade modules one at a time. We've found this approach works well with a modest set of updates, however for significantly out of date repos or files or a large number of files, you may wish to consider alternative approaches. +For legacy upgrades, the Patcher CLI offers an [interactive mode[(guides/update)] where you can browse all modules in the current working directory and below, browse available updates, and upgrade modules one at a time. We've found this approach works well with a modest set of updates, however for significantly out of date repos or files or a large number of files, you may wish to consider alternative approaches. For ongoing updates, you can use Patcher in conjunction with our published GitHub Action to automatically scan your repo's modules and [open pull requests](guides/ongoing-updates) with updated module versions. Opening one pull request for every update would be cumbersome, so Patcher supports a variety of [grouping modes](/concepts/grouping) that allow you to streamline your workflow. From 80083d4d5b7628f189496658a360018d135ba5cd Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:00:38 -0400 Subject: [PATCH 17/18] Update docs/2.0/docs/patcher/concepts/index.md --- docs/2.0/docs/patcher/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/concepts/index.md b/docs/2.0/docs/patcher/concepts/index.md index 238e9ee67..5c3d31149 100644 --- a/docs/2.0/docs/patcher/concepts/index.md +++ b/docs/2.0/docs/patcher/concepts/index.md @@ -34,4 +34,4 @@ For ongoing updates, you can use Patcher in conjunction with our published GitHu Patcher handles both non-breaking and breaking changes. For non-breaking changes, for the [Gruntwork Iac Library](library/concepts/overview), Patcher uses a set of pre-generated changelog files to identify the "next safe change," enabling upgrades to automatically bypass "empty" version upgrades where a module is available at a newer version but in fact has had no actual file changes. Upon request, we can work with you to implement these pre-generated changelogs in your organization. -For breaking changes, Patcher offers a systematic approach to doing code transformations -- we call these "patches" -- so that module consumers can automatically apply breaking changes to their modules. Or if Patcher detects a breaking change but a patch does not exist, Patcher updates the relevant module to the next breaking change and generates a README file in the folder with the updated file that outlines the release notes and details the breaking changes. Users review the README, address any necessary actions, and remove the file before rerunning Patcher. \ No newline at end of file +For breaking changes, Patcher offers a systematic approach to doing code transformations -- we call these "patches" -- so that module consumers can automatically apply breaking changes to their modules. Or if Patcher detects a breaking change but a patch does not exist, Patcher updates the relevant module to the next breaking change and generates a README file in the folder with the updated file that outlines the release notes and details the breaking changes. Users review the README, address any necessary actions, and remove the file before re-running Patcher. \ No newline at end of file From 9b971e59da82cdf47d99e9529560a9ff259f8222 Mon Sep 17 00:00:00 2001 From: Yousif Akbar <11247449+yhakbar@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:02:16 -0400 Subject: [PATCH 18/18] Update docs/2.0/docs/patcher/guides/ongoing-updates.md --- docs/2.0/docs/patcher/guides/ongoing-updates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.0/docs/patcher/guides/ongoing-updates.md b/docs/2.0/docs/patcher/guides/ongoing-updates.md index b7aea45eb..bd8775370 100644 --- a/docs/2.0/docs/patcher/guides/ongoing-updates.md +++ b/docs/2.0/docs/patcher/guides/ongoing-updates.md @@ -36,7 +36,7 @@ Individual pull requests can quickly get overwhelming. Once you've got this work ### Step-by-step setup for GitHub.com users #### 1. Create a GitHub token -- Create a token that can read patcher-cli and terrapatch-cli releases in your org (see [GitHub Personal Access Token Setup](#github-personal-access-token-setup) below). +- Create a token that can read patcher-cli and terrapatch-cli releases in your org (or `gruntwork-io`) (see [GitHub Personal Access Token Setup](#github-personal-access-token-setup) below). - Save it as a GitHub Actions secret named `PATCHER_CI_TOKEN`. :::warn