{"id":17821887,"url":"https://github.com/techpivot/terraform-module-releaser","last_synced_at":"2025-03-18T11:30:47.041Z","repository":{"id":257837878,"uuid":"870338508","full_name":"techpivot/terraform-module-releaser","owner":"techpivot","description":"GitHub Action to automate versioning, releases, and documentation for Terraform modules in monorepos.","archived":false,"fork":false,"pushed_at":"2024-10-24T05:28:16.000Z","size":2042,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-24T19:16:40.752Z","etag":null,"topics":["continuous-integration","devops-tools","github-action","release-automation","terraform","terraform-module","wiki"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/techpivot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-09T21:23:50.000Z","updated_at":"2024-10-24T17:34:45.000Z","dependencies_parsed_at":"2024-10-26T03:09:08.107Z","dependency_job_id":null,"html_url":"https://github.com/techpivot/terraform-module-releaser","commit_stats":null,"previous_names":["techpivot/terraform-module-releaser"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techpivot%2Fterraform-module-releaser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techpivot%2Fterraform-module-releaser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techpivot%2Fterraform-module-releaser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/techpivot%2Fterraform-module-releaser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/techpivot","download_url":"https://codeload.github.com/techpivot/terraform-module-releaser/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243925492,"owners_count":20369906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuous-integration","devops-tools","github-action","release-automation","terraform","terraform-module","wiki"],"created_at":"2024-10-27T17:27:24.719Z","updated_at":"2025-03-18T11:30:47.034Z","avatar_url":"https://github.com/techpivot.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Terraform Module Releaser\n\n\u003csup\u003e\u003cb\u003eA GitHub Action for managing Terraform modules in GitHub monorepos, automating versioning, releases, and\ndocumentation.\u003c/b\u003e\u003c/sup\u003e\n\n[![Latest GitHub Release](https://img.shields.io/github/release/techpivot/terraform-module-releaser.svg?style=flat-square)][1]\n[![GitHub Marketplace](https://img.shields.io/badge/marketplace-terraform--module--releaser-blue?logo=github\u0026style=flat-square)][2]\n![CI](https://github.com/techpivot/terraform-module-releaser/actions/workflows/ci.yml/badge.svg?event=pull_request)\n[![Lint](https://github.com/techpivot/terraform-module-releaser/actions/workflows/lint.yml/badge.svg)][3]\n[![CodeQL](https://github.com/techpivot/terraform-module-releaser/actions/workflows/codeql-analysis.yml/badge.svg)][4]\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=terraform-module-releaser\u0026metric=alert_status)][5]\n[![Coverage](./assets/coverage-badge.svg)](./assets/coverage-badge.svg)\n\n[1]: https://github.com/techpivot/terraform-module-releaser/releases/latest\n[2]: https://github.com/marketplace/actions/terraform-module-releaser\n[3]: https://github.com/techpivot/terraform-module-releaser/actions/workflows/lint.yml\n[4]: https://github.com/techpivot/terraform-module-releaser/actions/workflows/codeql-analysis.yml\n[5]: https://sonarcloud.io/summary/new_code?id=terraform-module-releaser\n\nSimplify the management of Terraform modules in your monorepo with this **GitHub Action**. It automates module-specific\nversioning and releases by creating proper Git tags and GitHub releases based on your commit messages. Each module\nmaintains independence while living in the same repository, with proper isolation for clean dependency management.\nAdditionally, the action generates a beautifully crafted wiki for each module, complete with readme information, usage\nexamples, Terraform-docs details, and a full changelog.\n\n## 🚀 Features\n\n- **Efficient Module Tagging** – Only includes module directory content, dramatically improving Terraform performance.\n- **Smart Versioning** – Automatically determines release types (major, minor, patch) based on commit messages.\n- **Comprehensive Wiki** – Generates beautiful documentation with usage examples, terraform-docs output, and full\n  changelogs.\n- **Release Automation** – Creates GitHub releases, pull request comments, and version tags with minimal effort.\n- **Self-Maintaining** – Automatically removes tags from deleted modules, keeping your repository clean and organized.\n- **100% GitHub Native** – No external dependencies or services required for modules or operation, everything stays\n  within your GitHub ecosystem.\n- **Zero Configuration** – Works out-of-the-box with sensible defaults for immediate productivity.\n- **Flexible \u0026 Extensible** – Customizable settings to precisely match your team's specific workflow requirements.\n\n## Demo\n\nCheck out our [Terraform Modules Demo](https://github.com/techpivot/terraform-modules-demo) repository for a practical\nexample of how to use this action in a monorepo setup. See real-world usage in action:\n\n- [**Pull Request - Initial**](https://github.com/techpivot/terraform-modules-demo/pull/1)\n- [**Pull Request - Module Changes**](https://github.com/techpivot/terraform-modules-demo/pull/2)\n- [**Wiki**](https://github.com/techpivot/terraform-modules-demo/wiki)\n- [**Releases**](https://github.com/techpivot/terraform-modules-demo/releases)\n- [**_More Pull Request Examples_**](https://github.com/techpivot/terraform-modules-demo/pulls?q=is%3Apr+is%3Aclosed)\n\n## Screenshots\n\n\u003cp float=\"left\" align=\"center\"\u003e\n  \u003cimg src=\"screenshots/wiki-sidebar.jpg\"\n    alt=\"Wiki Sidebar\" style=\"width: 299px; height: auto; \" /\u003e\n  \u003cimg src=\"screenshots/pr-initial-module-release.jpg\"\n    alt=\"PR Initial Module Release\" style=\"width: 619px; height: auto;\" /\u003e\n  \u003cimg src=\"screenshots/pr-separate-modules-updating.jpg\"\n    alt=\"PR Separate Modules Updating\" style=\"width: 504px; height: auto;\" /\u003e\n  \u003cimg src=\"screenshots/wiki-changelog.jpg\"\n    alt=\"Wiki Changelog\" style=\"width: 500px; height: auto;\" /\u003e\n  \u003cimg src=\"screenshots/wiki-usage.jpg\"\n    alt=\"Wiki Usage\" style=\"width: 500px; height: auto;\" /\u003e\n  \u003cimg src=\"screenshots/module-contents-explicit-dir-only.jpg\"\n    alt=\"Module Contents Explicit Dir Only\" style=\"width: 500px;\" /\u003e\n  \u003cimg src=\"screenshots/release-details.jpg\"\n    alt=\"Release Details\" style=\"width: 500px; height: auto;\" /\u003e\n  \u003cimg src=\"screenshots/wiki-module-example.jpg\"\n    alt=\"Wiki Module Example\" style=\"width: 500px; height:\" /\u003e\n\u003c/p\u003e\n\n## Getting Started\n\n### Step 1: Ensure GitHub Wiki is Enabled\n\nBefore using this action, make sure that the wiki is enabled and initialized for your repository:\n\n1. Go to your repository's homepage.\n1. Navigate to the **Settings** tab.\n1. Under the **Features** section, ensure the **Wikis** option is checked to enable the GitHub Wiki.\n1. Navigate to the **Wiki** tab on your repository.\n1. Click the **Create the first page** button and add a basic title like **Home** to initialize the wiki with an initial\n   commit.\n1. Save the changes to ensure your wiki is not empty when the GitHub Action updates it with module information.\n\n### Step 2: Configure the Action\n\nAdd the following YAML to your `.github/workflows` directory:\n\n#### terraform-module-releaser.yml\n\n```yml\nname: Terraform Module Releaser\non:\n  pull_request:\n    types: [opened, reopened, synchronize, closed] # Closed required\n    branches:\n      - main\n\npermissions:\n  contents: write # Required for to push tags, create release, and push changes to the wiki\n  pull-requests: write # Required to comment on pull request\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Terraform Module Releaser\n        uses: techpivot/terraform-module-releaser@v1\n```\n\nThis configuration provides an out-of-the-box solution that should work for most projects, as the defaults are\nreasonably configured.\n\nIf you need to customize additional parameters, please refer to [Input Parameters](#input-parameters) section below.\n\n## Permissions\n\nBefore executing the GitHub Actions workflow, ensure that you have the necessary permissions set for accessing pull\nrequests and creating releases.\n\n- By default, this GitHub Action uses the\n  [`GITHUB_TOKEN`](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication)\n  associated with the workflow. To properly comment on pull requests and create tags/releases, the workflow permission\n  for `pull-requests` must be set to `\"write\"`.\n- Additionally, the workflow permission for `contents` must also be set to `\"write\"` to allow the action to create tags\n  and releases.\n- For security considerations and best practices when using the `github_token`, please refer to the\n  [Security Documentation](./security.md).\n- Ensure the **Restrict editing to users in teams with push access only** setting is enabled for public repositories, as\n  the GitHub Actions Bot can write to the wiki by default.\n\nIf the permissions are insufficient, the action may fail with a 403 error, indicating a lack of access to the necessary\nresources.\n\n## Directory Structure Best Practices\n\n- Avoid placing nested Terraform modules within a sub-directory of another module, as this practice can lead to issues\n  with dependency management and module separation. Instead, structure your repository with multiple levels of\n  folders/directories to organize modules while keeping each Terraform module isolated within its dedicated directory.\n  This approach promotes maintainability and helps ensure clarity across modules.\n\n- We recommend structuring modules with a top-level namespace that is related to a major provider (e.g., `aws`, `azure`,\n  or `null`). Within this namespace, use a nested directory to house the actual module with a name that corresponds\n  closely to its intended purpose or resource. For example:\n\n  ```shell\n  ├── aws\n  │   ├── vpc\n  │   └── ec2\n  ├── azure\n  │   ├── resource-group\n  │   └── storage-account\n  └── null\n      └── label\n  ```\n\n## Input Parameters\n\nWhile the out-of-the-box defaults are suitable for most use cases, you can further customize the action's behavior by\nconfiguring the following optional input parameters as needed.\n\n| Input                            | Description                                                                                                                                                                                                                                                                                                                                                                                          | Default                                    |\n| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |\n| `major-keywords`                 | Keywords in commit messages that indicate a major release                                                                                                                                                                                                                                                                                                                                            | `major change,breaking change`             |\n| `minor-keywords`                 | Keywords in commit messages that indicate a minor release                                                                                                                                                                                                                                                                                                                                            | `feat,feature`                             |\n| `patch-keywords`                 | Keywords in commit messages that indicate a patch release                                                                                                                                                                                                                                                                                                                                            | `fix,chore,docs`                           |\n| `default-first-tag`              | Specifies the default tag version                                                                                                                                                                                                                                                                                                                                                                    | `v1.0.0`                                   |\n| `terraform-docs-version`         | Specifies the terraform-docs version used to generate documentation for the wiki                                                                                                                                                                                                                                                                                                                     | `v0.19.0`                                  |\n| `delete-legacy-tags`             | Specifies a boolean that determines whether tags and releases from Terraform modules that have been deleted should be automatically removed                                                                                                                                                                                                                                                          | `true`                                     |\n| `disable-wiki`                   | Whether to disable wiki generation for Terraform modules                                                                                                                                                                                                                                                                                                                                             | `false`                                    |\n| `wiki-sidebar-changelog-max`     | An integer that specifies how many changelog entries are displayed in the sidebar per module                                                                                                                                                                                                                                                                                                         | `5`                                        |\n| `disable-branding`               | Controls whether a small branding link to the action's repository is added to PR comments. Recommended to leave enabled to support OSS.                                                                                                                                                                                                                                                              | `false`                                    |\n| `module-path-ignore`             | Comma separated list of module paths to completely ignore (relative to working directory). This will prevent any versioning, release, or documentation for these modules.                                                                                                                                                                                                                            | `` (empty)                                 |\n| `module-change-exclude-patterns` | A comma-separated list of file patterns to exclude from triggering version changes in Terraform modules. Patterns follow glob syntax (e.g., `.gitignore,_.md`) and are relative to each Terraform module directory. Files matching these patterns will not affect version changes. **WARNING**: Avoid excluding '`_.tf`' files, as they are essential for module detection and versioning processes. | `.gitignore, *.md, *.tftest.hcl, tests/**` |\n| `module-asset-exclude-patterns`  | A comma-separated list of file patterns to exclude when bundling a Terraform module for tag/release. Patterns follow glob syntax (e.g., `tests/\\*\\*`) and are relative to each Terraform module directory. Files matching these patterns will be excluded from the bundled output.                                                                                                                   | `.gitignore, *.md, *.tftest.hcl, tests/**` |\n| `use-ssh-source-format`          | If enabled, all links to source code in generated Wiki documentation will use SSH standard format (e.g., `git::ssh://git@github.com/owner/repo.git`) instead of HTTPS format (`git::https://github.com/owner/repo.git`)                                                                                                                                                                              | `false`                                    |\n\n### Understanding the filtering options\n\n- **`module-path-ignore`**: Completely ignores specified module paths. Any module whose path matches any pattern in this\n  list will not be processed at all by the action. This is useful for:\n\n  - Excluding example modules (e.g., `**/examples/**`)\n  - Skipping test modules (e.g., `**/test/**`)\n  - Ignoring documentation-focused modules (e.g., `**/docs/**`)\n  - Excluding entire directories or paths that contain Terraform files but shouldn't be versioned as modules\n\n  Example:\n\n  ```yaml\n  module-path-ignore: \"**/examples/**,**/test/**,root-modules\"\n  ```\n\n- **`module-change-exclude-patterns`**: These patterns determine which file changes are _ignored_ when checking if a\n  module needs a new release. For example, changes to documentation, examples, or workflow files typically don't require\n  a new module release.\n- **`module-asset-exclude-patterns`**: When building a release asset for a module, these patterns determine which files\n  are _excluded_ from the asset. This helps reduce the asset size by omitting test files, examples, documentation, etc.\n\nAll pattern matching is implemented using [minimatch](https://github.com/isaacs/minimatch), which supports glob patterns\nsimilar to those used in `.gitignore` files. For more details on the pattern matching implementation, see our\n[source code](https://github.com/techpivot/terraform-module-releaser/blob/main/src/utils/file.ts) or visit the\n[minimatch documentation](https://github.com/isaacs/minimatch).\n\n### Example Usage with Inputs\n\n```yml\nname: Terraform Module Releaser\non:\n  pull_request:\n    types: [opened, reopened, synchronize, closed] # Closed required\n    branches:\n      - main\n\npermissions:\n  contents: write # Required for to push tags, create release, and push changes to the wiki\n  pull-requests: write # Required to comment on pull request\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Terraform Module Releaser\n        uses: techpivot/terraform-module-releaser@v1\n        with:\n          major-keywords: major update,breaking change\n          minor-keywords: feat,feature\n          patch-keywords: fix,chore,docs\n          default-first-tag: v1.0.0\n          terraform-docs-version: v0.19.0\n          delete-legacy-tags: true\n          disable-wiki: false\n          wiki-sidebar-changelog-max: 10\n          module-change-exclude-patterns: .gitignore,*.md,*.tftest.hcl,tests/**\n          module-asset-exclude-patterns: .gitignore,*.md,*.tftest.hcl,tests/**\n          use-ssh-source-format: false\n          module-path-ignore: path/to/ignore1,path/to/ignore2\n```\n\n## Outputs\n\nThe following outputs are available from this action:\n\n| Output                 | Type     | Description                                                                                                |\n| ---------------------- | -------- | ---------------------------------------------------------------------------------------------------------- |\n| `changed-module-names` | `string` | JSON array of module names that were changed in the current pull request                                   |\n| `changed-module-paths` | `string` | JSON array of file system paths to the modules that were changed                                           |\n| `changed-modules-map`  | `string` | JSON object mapping module names to their change details including current tag, next tag, and release type |\n| `all-module-names`     | `string` | JSON array of all module names found in the repository                                                     |\n| `all-module-paths`     | `string` | JSON array of file system paths to all modules in the repository                                           |\n| `all-modules-map`      | `string` | JSON object mapping all module names to their details including path, latest tag, and latest tag version   |\n\n### Example Output Structure\n\n```json\n{\n  \"changed-modules-map\": {\n    \"aws/vpc\": {\n      \"path\": \"modules/aws/vpc\",\n      \"currentTag\": \"aws/vpc/v1.0.0\",\n      \"nextTag\": \"aws/vpc/v1.1.0\",\n      \"releaseType\": \"minor\"\n    }\n  },\n  \"all-modules-map\": {\n    \"aws/vpc\": {\n      \"path\": \"modules/aws/vpc\",\n      \"latestTag\": \"aws/vpc/v1.0.0\",\n      \"latestTagVersion\": \"v1.0.0\"\n    },\n    \"aws/s3\": {\n      \"path\": \"modules/aws/s3\",\n      \"latestTag\": \"aws/s3/v2.1.0\",\n      \"latestTagVersion\": \"v2.1.0\"\n    }\n  }\n}\n```\n\n## Inspiration\n\nThis action was inspired by the blog post\n[GitHub-Powered Terraform Modules Monorepo](https://cloudchronicles.blog/blog/GitHub-Powered-Terraform-Modules-Monorepo/)\nby Piotr Krukowski.\n\n## Notes\n\n- This action uses [Conventional Commits](https://www.conventionalcommits.org/) to automatically determine the release\n  type _(major, minor, or patch)_ based on commit messages. This behavior is configurable via\n  [inputs](#input-parameters).\n- Versioning is done using [Semantic Versioning (SemVer)](https://semver.org/), which provides a clear and consistent\n  way to manage module versions.\n- Commit messages are linked to the respective Terraform directories _(handling PRs that may have separate modules and\n  changed files)_.\n- Unlike the original inspiration, which relied on labels for tagging and versioning, this action leverages commit\n  messages to determine the release type. This approach simplifies the process and eliminates the complexity introduced\n  by labels, which were PR-specific and didn't account for individual commits per module. By using commit messages, we\n  can now accurately tag and version only the relevant commits, providing a more precise and efficient release\n  management process.\n- **100% GitHub-based**: This action has no external dependencies, eliminating the need for additional authentication\n  and complexity. Unlike earlier variations that stored built module assets in external services like Amazon S3, this\n  action keeps everything within GitHub, providing a self-contained and streamlined solution for managing Terraform\n  modules.\n- **Pull Request-based workflow**: This action runs on the pull_request event, using pull request comments to track\n  permanent releases tied to commits. This method ensures persistence, unlike Action Artifacts, which expire. As a\n  result, the module does not support non-PR workflows, such as direct pushes to the default branch.\n\n## License\n\nThe scripts and documentation in this project are released under the [MIT License](./LICENSE.md).\n\n## Security\n\nFor detailed information about security practices and guidelines, check out the [Security Documentation](./security.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechpivot%2Fterraform-module-releaser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechpivot%2Fterraform-module-releaser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechpivot%2Fterraform-module-releaser/lists"}