-
Notifications
You must be signed in to change notification settings - Fork 43
Improve Patcher documentation: clarify use cases and add simplified GitHub Actions guide #2723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 12 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
12b5898
Improve Patcher documentation: clarify use cases and add simplified G…
devin-ai-integration[bot] 5f7bb89
Fix spellcheck error and add GitHub fine-grained token setup document…
devin-ai-integration[bot] c585c84
Add warning on github org
josh-padnick b4b5fe8
Add patcher-action v2 to v3 migration documentation
devin-ai-integration[bot] 59d533b
Merge branch 'devin/1756506141-improve-patcher-docs' of https://git-m…
devin-ai-integration[bot] 7ebc501
Update Patcher overview to reflect the latest available info.
josh-padnick 8e35e13
Update description for "ongoing updates." Still needs work, so commit…
josh-padnick 76347b1
docs(patcher): align ongoing-updates guide with patcher-action v3 cus…
devin-ai-integration[bot] 8c6bad7
docs(patcher): clarify step-by-step setup and authentication for GitH…
devin-ai-integration[bot] 2684728
docs(patcher): dedupe and keep a single step-by-step setup section
devin-ai-integration[bot] c35163a
Lots of updates to the Patcher self-hosting docs, walking through eve…
josh-padnick 5385c3d
docs(patcher): resolve TODOs, clarify enterprise two-job workflow, st…
devin-ai-integration[bot] 05dc55a
Add small note to docs.
josh-padnick 3a8dbbf
Update docs/2.0/docs/patcher/concepts/index.md
yhakbar 45fbe75
Update docs/2.0/docs/patcher/concepts/index.md
yhakbar 84241b6
Update docs/2.0/docs/patcher/concepts/index.md
yhakbar 7c6f1fb
Update docs/2.0/docs/patcher/concepts/index.md
yhakbar 80083d4
Update docs/2.0/docs/patcher/concepts/index.md
yhakbar 9b971e5
Update docs/2.0/docs/patcher/guides/ongoing-updates.md
yhakbar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: | ||
yhakbar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
- 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: | ||
yhakbar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
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. | ||
yhakbar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
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. | ||
yhakbar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,308 @@ | ||
# Ongoing Updates | ||
|
||
## Overview | ||
|
||
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. 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 | ||
|
||
## Which CI systems are supported? | ||
|
||
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 | ||
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 | ||
|
||
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. **`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. 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). | ||
yhakbar marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
- Save it as a GitHub Actions secret named `PATCHER_CI_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. | ||
::: | ||
|
||
#### 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. | ||
|
||
#### 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. 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. | ||
|
||
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. | ||
::: | ||
|
||
#### 4. Run and review! | ||
- Manually run the GitHub Actions workflow the first time to validate configuration. | ||
- Review the generated PRs and merge as desired. | ||
|
||
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 | ||
|
||
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/terrapatch-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). | ||
|
||
### For GitHub.com users | ||
|
||
Create a new file `.github/workflows/patcher-updates.yml` in your repository: | ||
|
||
```yml | ||
name: Patcher 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: | ||
dependencies: ${{ steps.get-deps.outputs.dependencies }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- id: get-deps | ||
uses: gruntwork-io/patcher-action@v2 | ||
with: | ||
patcher_command: report | ||
read_token: ${{ secrets.PATCHER_CI_TOKEN }} | ||
working_dir: ./ | ||
|
||
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: | ||
# Make sure Patcher has enough Git history to correctly determine changes | ||
fetch-depth: 0 | ||
|
||
- 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 }}" | ||
``` | ||
### For GitHub Enterprise users | ||
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. | ||
Here is an example showing two jobs in a single workflow: | ||
```yml | ||
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: ./ | ||
|
||
# 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 }} | ||
working_dir: ./ | ||
dependency: ${{ matrix.dependency }} | ||
pull_request_title: "[Patcher] Update ${{ matrix.dependency }}" | ||
pull_request_branch: "patcher-updates-${{ matrix.dependency }}" | ||
``` | ||
## GitHub Personal Access Token Setup | ||
You'll need to manually create a GitHub token that has permission to access the Patcher CLI and Terrapatch CLI tools. | ||
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: | ||
#### 1. Navigate to GitHub Settings | ||
- 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 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. | ||
|
||
:::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. | ||
::: | ||
|
||
#### 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 as a GitHub Actions secret named `PATCHER_CI_TOKEN` in the repository where the workflow runs. | ||
|
||
:::warn | ||
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: | ||
|
||
```yml | ||
- uses: gruntwork-io/patcher-action@v2 | ||
with: | ||
patcher_command: report | ||
read_token: ${{ secrets.PATCHER_CI_TOKEN }} | ||
exclude_dirs: "examples/**,tests/**" | ||
working_dir: ./ | ||
``` | ||
|
||
### Update Strategies | ||
Control how aggressively Patcher updates dependencies: | ||
|
||
```yml | ||
- uses: gruntwork-io/patcher-action@v2 | ||
with: | ||
patcher_command: update | ||
update_token: ${{ secrets.PATCHER_CI_TOKEN }} | ||
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 | ||
update_token: ${{ secrets.PATCHER_CI_TOKEN }} | ||
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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.