diff --git a/.github/workflows/test-matrix-2-levels.yml b/.github/workflows/test-matrix-2-levels.yml new file mode 100644 index 0000000..9d62be7 --- /dev/null +++ b/.github/workflows/test-matrix-2-levels.yml @@ -0,0 +1,57 @@ +name: Test atmos-affected-stacks with 2 levels of nested matrices +on: +# # Uncomment when test added first time to register workflow and comment it back after workflow would be registered +# # +# # Added pull_request to register workflow from the PR. +# # Read more https://stackoverflow.com/questions/63362126/github-actions-how-to-run-a-workflow-created-on-a-non-master-branch-from-the-wo +# pull_request: {} + workflow_dispatch: {} + +jobs: + setup: + runs-on: ubuntu-latest + steps: + - name: Setup + run: echo "Do setup" + + test: + runs-on: ubuntu-latest + needs: [setup] + continue-on-error: true + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: add mock atmos to the path + run: echo "./tests/fixtures" >> $GITHUB_PATH + + - uses: ./ + id: current + with: + install-atmos: false + atmos-gitops-config-path: "./tests/atmos-gitops.yaml" + nested-matrices-count: '2' + + outputs: + affected: "${{ steps.current.outputs.affected }}" + matrix: "${{ steps.current.outputs.matrix }}" + + assert: + runs-on: ubuntu-latest + needs: [test] + steps: + - uses: nick-fields/assert-action@v1 + with: + expected: '[{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-ue2-root","stack_slug":"core-ue2-root-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-audit","stack_slug":"core-gbl-audit-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-datadog-integration","spacelift_stack":"core-gbl-auto-datadog-integration","affected":"component"},{"component":"infrastructure-cplive-plat","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-plat","spacelift_stack":"core-gbl-auto-infrastructure-cplive-plat","affected":"stack.vars"},{"component":"infrastructure-cplive-core","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-core","spacelift_stack":"core-gbl-auto-infrastructure-cplive-core","affected":"stack.vars"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"plat-gbl-prod","stack_slug":"plat-gbl-prod-datadog-integration","spacelift_stack":"plat-gbl-prod-datadog-integration","affected":"component"}]' + actual: "${{ needs.test.outputs.affected }}" + + - uses: nick-fields/assert-action@v1 + with: + expected: '{"include":[' + actual: "${{ needs.test.outputs.matrix }}" + comparison: contains + + - uses: nick-fields/assert-action@v1 + with: + expected: '{"include":[{"name":"core-audit","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-gbl-audit\",\"stack_slug\":\"core-gbl-audit-datadog-integration\",\"affected\":\"component\"}]}"},{"name":"core-auto","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-datadog-integration\",\"spacelift_stack\":\"core-gbl-auto-datadog-integration\",\"affected\":\"component\"},{\"component\":\"infrastructure-cplive-core\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/spacelift\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-infrastructure-cplive-core\",\"spacelift_stack\":\"core-gbl-auto-infrastructure-cplive-core\",\"affected\":\"stack.vars\"},{\"component\":\"infrastructure-cplive-plat\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/spacelift\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-infrastructure-cplive-plat\",\"spacelift_stack\":\"core-gbl-auto-infrastructure-cplive-plat\",\"affected\":\"stack.vars\"}]}"},{"name":"core-root","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-ue2-root\",\"stack_slug\":\"core-ue2-root-datadog-integration\",\"affected\":\"component\"}]}"},{"name":"plat-prod","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"plat-gbl-prod\",\"stack_slug\":\"plat-gbl-prod-datadog-integration\",\"spacelift_stack\":\"plat-gbl-prod-datadog-integration\",\"affected\":\"component\"}]}"}]}' + actual: "${{ needs.test.outputs.matrix }}" diff --git a/.github/workflows/test-matrix-3-levels.yml b/.github/workflows/test-matrix-3-levels.yml new file mode 100644 index 0000000..915fada --- /dev/null +++ b/.github/workflows/test-matrix-3-levels.yml @@ -0,0 +1,57 @@ +name: Test atmos-affected-stacks with 3 levels of nested matrices +on: +# # Uncomment when test added first time to register workflow and comment it back after workflow would be registered +# # +# # Added pull_request to register workflow from the PR. +# # Read more https://stackoverflow.com/questions/63362126/github-actions-how-to-run-a-workflow-created-on-a-non-master-branch-from-the-wo +# pull_request: {} + workflow_dispatch: {} + +jobs: + setup: + runs-on: ubuntu-latest + steps: + - name: Setup + run: echo "Do setup" + + test: + runs-on: ubuntu-latest + needs: [setup] + continue-on-error: true + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: add mock atmos to the path + run: echo "./tests/fixtures" >> $GITHUB_PATH + + - uses: ./ + id: current + with: + install-atmos: false + atmos-gitops-config-path: "./tests/atmos-gitops.yaml" + nested-matrices-count: '3' + + outputs: + affected: "${{ steps.current.outputs.affected }}" + matrix: "${{ steps.current.outputs.matrix }}" + + assert: + runs-on: ubuntu-latest + needs: [test] + steps: + - uses: nick-fields/assert-action@v1 + with: + expected: '[{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-ue2-root","stack_slug":"core-ue2-root-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-audit","stack_slug":"core-gbl-audit-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-datadog-integration","spacelift_stack":"core-gbl-auto-datadog-integration","affected":"component"},{"component":"infrastructure-cplive-plat","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-plat","spacelift_stack":"core-gbl-auto-infrastructure-cplive-plat","affected":"stack.vars"},{"component":"infrastructure-cplive-core","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-core","spacelift_stack":"core-gbl-auto-infrastructure-cplive-core","affected":"stack.vars"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"plat-gbl-prod","stack_slug":"plat-gbl-prod-datadog-integration","spacelift_stack":"plat-gbl-prod-datadog-integration","affected":"component"}]' + actual: "${{ needs.test.outputs.affected }}" + + - uses: nick-fields/assert-action@v1 + with: + expected: '{"include":[' + actual: "${{ needs.test.outputs.matrix }}" + comparison: contains + + - uses: nick-fields/assert-action@v1 + with: + expected: '{"include":[{"name":"core-audit","items":"{\"include\":[{\"name\":\"core-gbl-audit-datadog-integration - core-gbl-audit-datadog-integration\",\"items\":\"{\\\"include\\\":[{\\\"component\\\":\\\"datadog-integration\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/datadog-integration\\\",\\\"stack\\\":\\\"core-gbl-audit\\\",\\\"stack_slug\\\":\\\"core-gbl-audit-datadog-integration\\\",\\\"affected\\\":\\\"component\\\"}]}\"}]}"},{"name":"core-auto","items":"{\"include\":[{\"name\":\"core-gbl-auto-datadog-integration - core-gbl-auto-infrastructure-cplive-plat\",\"items\":\"{\\\"include\\\":[{\\\"component\\\":\\\"datadog-integration\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/datadog-integration\\\",\\\"stack\\\":\\\"core-gbl-auto\\\",\\\"stack_slug\\\":\\\"core-gbl-auto-datadog-integration\\\",\\\"spacelift_stack\\\":\\\"core-gbl-auto-datadog-integration\\\",\\\"affected\\\":\\\"component\\\"},{\\\"component\\\":\\\"infrastructure-cplive-core\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/spacelift\\\",\\\"stack\\\":\\\"core-gbl-auto\\\",\\\"stack_slug\\\":\\\"core-gbl-auto-infrastructure-cplive-core\\\",\\\"spacelift_stack\\\":\\\"core-gbl-auto-infrastructure-cplive-core\\\",\\\"affected\\\":\\\"stack.vars\\\"},{\\\"component\\\":\\\"infrastructure-cplive-plat\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/spacelift\\\",\\\"stack\\\":\\\"core-gbl-auto\\\",\\\"stack_slug\\\":\\\"core-gbl-auto-infrastructure-cplive-plat\\\",\\\"spacelift_stack\\\":\\\"core-gbl-auto-infrastructure-cplive-plat\\\",\\\"affected\\\":\\\"stack.vars\\\"}]}\"}]}"},{"name":"core-root","items":"{\"include\":[{\"name\":\"core-ue2-root-datadog-integration - core-ue2-root-datadog-integration\",\"items\":\"{\\\"include\\\":[{\\\"component\\\":\\\"datadog-integration\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/datadog-integration\\\",\\\"stack\\\":\\\"core-ue2-root\\\",\\\"stack_slug\\\":\\\"core-ue2-root-datadog-integration\\\",\\\"affected\\\":\\\"component\\\"}]}\"}]}"},{"name":"plat-prod","items":"{\"include\":[{\"name\":\"plat-gbl-prod-datadog-integration - plat-gbl-prod-datadog-integration\",\"items\":\"{\\\"include\\\":[{\\\"component\\\":\\\"datadog-integration\\\",\\\"component_type\\\":\\\"terraform\\\",\\\"component_path\\\":\\\"components/terraform/datadog-integration\\\",\\\"stack\\\":\\\"plat-gbl-prod\\\",\\\"stack_slug\\\":\\\"plat-gbl-prod-datadog-integration\\\",\\\"spacelift_stack\\\":\\\"plat-gbl-prod-datadog-integration\\\",\\\"affected\\\":\\\"component\\\"}]}\"}]}"}]}' + actual: "${{ needs.test.outputs.matrix }}" diff --git a/.github/workflows/test-positive.yml b/.github/workflows/test-positive.yml index 0a04d23..3fdaa2f 100644 --- a/.github/workflows/test-positive.yml +++ b/.github/workflows/test-positive.yml @@ -23,13 +23,14 @@ jobs: uses: actions/checkout@v3 - name: add mock atmos to the path - run: echo "./fixtures" >> $GITHUB_PATH + run: echo "./tests/fixtures" >> $GITHUB_PATH - uses: ./ id: current with: install-atmos: false - atmos-config-path: "./components/terraform/test" + atmos-gitops-config-path: "./tests/atmos-gitops.yaml" + outputs: affected: "${{ steps.current.outputs.affected }}" matrix: "${{ steps.current.outputs.matrix }}" @@ -40,11 +41,16 @@ jobs: steps: - uses: nick-fields/assert-action@v1 with: - expected: '{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-dns","stack_slug":"core-gbl-dns-datadog-integration","spacelift_stack":"core-gbl-dns-datadog-integration","affected":"component"}' + expected: '[{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-ue2-root","stack_slug":"core-ue2-root-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-audit","stack_slug":"core-gbl-audit-datadog-integration","affected":"component"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-datadog-integration","spacelift_stack":"core-gbl-auto-datadog-integration","affected":"component"},{"component":"infrastructure-cplive-plat","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-plat","spacelift_stack":"core-gbl-auto-infrastructure-cplive-plat","affected":"stack.vars"},{"component":"infrastructure-cplive-core","component_type":"terraform","component_path":"components/terraform/spacelift","stack":"core-gbl-auto","stack_slug":"core-gbl-auto-infrastructure-cplive-core","spacelift_stack":"core-gbl-auto-infrastructure-cplive-core","affected":"stack.vars"},{"component":"datadog-integration","component_type":"terraform","component_path":"components/terraform/datadog-integration","stack":"plat-gbl-prod","stack_slug":"plat-gbl-prod-datadog-integration","spacelift_stack":"plat-gbl-prod-datadog-integration","affected":"component"}]' actual: "${{ needs.test.outputs.affected }}" - comparison: contains + - uses: nick-fields/assert-action@v1 with: expected: '{"include":[' actual: "${{ needs.test.outputs.matrix }}" comparison: contains + + - uses: nick-fields/assert-action@v1 + with: + expected: '{"include":[{"name":"core-audit","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-gbl-audit\",\"stack_slug\":\"core-gbl-audit-datadog-integration\",\"affected\":\"component\"}]}"},{"name":"core-auto","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-datadog-integration\",\"spacelift_stack\":\"core-gbl-auto-datadog-integration\",\"affected\":\"component\"},{\"component\":\"infrastructure-cplive-core\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/spacelift\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-infrastructure-cplive-core\",\"spacelift_stack\":\"core-gbl-auto-infrastructure-cplive-core\",\"affected\":\"stack.vars\"},{\"component\":\"infrastructure-cplive-plat\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/spacelift\",\"stack\":\"core-gbl-auto\",\"stack_slug\":\"core-gbl-auto-infrastructure-cplive-plat\",\"spacelift_stack\":\"core-gbl-auto-infrastructure-cplive-plat\",\"affected\":\"stack.vars\"}]}"},{"name":"core-root","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"core-ue2-root\",\"stack_slug\":\"core-ue2-root-datadog-integration\",\"affected\":\"component\"}]}"},{"name":"plat-prod","items":"{\"include\":[{\"component\":\"datadog-integration\",\"component_type\":\"terraform\",\"component_path\":\"components/terraform/datadog-integration\",\"stack\":\"plat-gbl-prod\",\"stack_slug\":\"plat-gbl-prod-datadog-integration\",\"spacelift_stack\":\"plat-gbl-prod-datadog-integration\",\"affected\":\"component\"}]}"}]}' + actual: "${{ needs.test.outputs.matrix }}" diff --git a/README.md b/README.md index 7a718f4..f6c4dab 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,6 @@ A GitHub Action to get a list of affected atmos stacks for a pull request --- This project is part of our comprehensive ["SweetOps"](https://cpco.io/sweetops) approach towards DevOps. -[][share_email] -[][share_googleplus] -[][share_facebook] -[][share_reddit] -[][share_linkedin] -[][share_twitter] - - It's 100% Open Source and licensed under the [APACHE2](LICENSE). @@ -64,11 +56,35 @@ raw list of affected stacks as an output as well as a matrix that can be used fu +## Usage -## Usage +### Config + +The action expects the atmos gitops configuration file to be present in the repository in `./.github/config/atmos-gitops.yaml`. +The config should have the following structure: + +```yaml + atmos-version: 1.45.3 + atmos-config-path: ./rootfs/usr/local/etc/atmos/ + terraform-state-bucket: cptest-core-ue2-auto-gitops + terraform-state-table: cptest-core-ue2-auto-gitops + terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha + terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-version: 1.5.2 + aws-region: us-east-2 + enable-infracost: false + sort-by: .stack_slug + group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-") +``` + +> [!IMPORTANT] +> **Please note!** the `terraform-state-*` parameters refer to the S3 Bucket and corresponding meta storage DynamoDB table used to store the Terraform Plan files, and not the "Terraform State". These parameters will be renamed in a subsequent release. + +### Workflow example ```yaml name: Pull Request @@ -83,11 +99,81 @@ raw list of affected stacks as an output as well as a matrix that can be used fu steps: - uses: actions/checkout@v3 - id: affected - uses: cloudposse/github-action-atmos-affected-stacks@feature/initial-implementation + uses: cloudposse/github-action-atmos-affected-stacks@v2 + with: + atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml + nested-matrices-count: 1 outputs: affected: ${{ steps.affected.outputs.affected }} matrix: ${{ steps.affected.outputs.matrix }} + + atmos-plan: + needs: ["atmos-affected"] + if: ${{ needs.atmos-affected.outputs.has-affected-stacks }} + name: ${{ matrix.stack_slug }} + runs-on: ['self-hosted'] + strategy: + max-parallel: 10 + fail-fast: false # Don't fail fast to avoid locking TF State + matrix: ${{ fromJson(needs.atmos-affected.outputs.stacks) }} + ## Avoid running the same stack in parallel mode (from different workflows) + concurrency: + group: ${{ matrix.stack_slug }} + cancel-in-progress: false + steps: + - name: Plan Atmos Component + uses: cloudposse/github-action-atmos-terraform-plan@v1 + with: + component: ${{ matrix.component }} + stack: ${{ matrix.stack }} +``` + +### Migrating from `v1` to `v2` + +`v2` moves most of the `inputs` to the Atmos GitOps config path `./.github/config/atmos-gitops.yaml`. Simply create this file, transfer your settings to it, then remove the corresponding arguments from your invocations of the `cloudposse/github-action-atmos-affected-stacks` action. + +| name | +|--------------------------| +| `atmos-version` | +| `atmos-config-path` | +| `terraform-state-bucket` | +| `terraform-state-table` | +| `terraform-state-role` | +| `terraform-plan-role` | +| `terraform-apply-role` | +| `terraform-version` | +| `aws-region` | +| `enable-infracost` | + + +If you want the same behavior in `v2` as in `v1` you should create config `./.github/config/atmos-gitops.yaml` with the same variables as in `v1` inputs. + +```yaml + - name: Determine Affected Stacks + uses: cloudposse/github-action-atmos-affected-stacks@v2 + id: affected + with: + atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml +``` + +Which would produce the same behavior as in `v1`, doing this: + +```yaml + - name: Determine Affected Stacks + uses: cloudposse/github-action-atmos-affected-stacks@v1 + id: affected + with: + atmos-version: 1.45.3 + atmos-config-path: ./rootfs/usr/local/etc/atmos/ + terraform-state-bucket: cptest-core-ue2-auto-gitops + terraform-state-table: cptest-core-ue2-auto-gitops + terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha + terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-version: 1.5.2 + aws-region: us-east-2 + enable-infracost: false ``` @@ -101,16 +187,17 @@ raw list of affected stacks as an output as well as a matrix that can be used fu | Name | Description | Default | Required | |------|-------------|---------|----------| -| atmos-config-path | The path to the atmos.yaml file | atmos.yaml | false | -| atmos-version | The version of atmos to install if install-atmos is true | latest | false | +| atmos-gitops-config-path | The path to the atmos-gitops.yaml file | ./.github/config/atmos-gitops.yaml | false | +| atmos-include-spacelift-admin-stacks | Whether to include the Spacelift admin stacks of affected stacks in the output | false | false | +| base-ref | The base ref to checkout. If not provided, the head default branch is used. | N/A | false | | default-branch | The default branch to use for the base ref. | ${{ github.event.repository.default\_branch }} | false | -| head-ref | The head ref to checkout. If not provided, the head default branch is used. | N/A | false | +| head-ref | The head ref to checkout. If not provided, the head default branch is used. | ${{ github.sha }} | false | | install-atmos | Whether to install atmos | true | false | | install-jq | Whether to install jq | false | false | | install-terraform | Whether to install terraform | true | false | | jq-force | Whether to force the installation of jq | true | false | | jq-version | The version of jq to install if install-jq is true | 1.6 | false | -| terraform-version | The version of terraform to install if install-terraform is true | latest | false | +| nested-matrices-count | Number of nested matrices that should be returned as the output (from 1 to 3) | 2 | false | ## Outputs @@ -119,41 +206,65 @@ raw list of affected stacks as an output as well as a matrix that can be used fu |------|-------------| | affected | The affected stacks | | has-affected-stacks | Whether there are affected stacks | -| matrix | A matrix suitable for use for GitHub Actions of the affected stacks | +| matrix | The affected stacks as matrix structure suitable for extending matrix size workaround (see README) | +## Related Projects -## Share the Love +Check out these related projects. -Like this project? Please give it a ★ on [our GitHub](https://github.com/cloudposse/github-action-atmos-affected-stacks)! (it helps us **a lot**) -Are you using this project or any of our other projects? Consider [leaving a testimonial][testimonial]. =) +## References +For additional context, refer to some of these links. -## Related Projects -Check out these related projects. +## ✨ Contributing +This project is under active development, and we encourage contributions from our community. +Many thanks to our outstanding contributors: -## References + + + -For additional context, refer to some of these links. +### 🐛 Bug Reports & Feature Requests +Please use the [issue tracker](https://github.com/cloudposse/github-action-atmos-affected-stacks/issues) to report any bugs or file feature requests. +### 💻 Developing -## Help +If you are interested in being a contributor and want to get involved in developing this project or [help out](https://cpco.io/help-out) with our other projects, we would love to hear from you! Shoot us an [email][email]. -**Got a question?** We got answers. +In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. -File a GitHub [issue](https://github.com/cloudposse/github-action-atmos-affected-stacks/issues), send us an [email][email] or join our [Slack Community][slack]. + 1. **Fork** the repo on GitHub + 2. **Clone** the project to your own machine + 3. **Commit** changes to your own branch + 4. **Push** your work back up to your fork + 5. Submit a **Pull Request** so that we can review your changes -[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link] +**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request! -## DevOps Accelerator for Startups +### 🌎 Slack Community +Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. + +### 📰 Newsletter + +Sign up for [our newsletter][newsletter] that covers everything on our technology radar. Receive updates on what we're up to on GitHub as well as awesome new projects we discover. + +### 📆 Office Hours + +[Join us every Wednesday via Zoom][office_hours] for our weekly "Lunch & Learn" sessions. It's **FREE** for everyone! + +## About + +This project is maintained and funded by [Cloud Posse, LLC][website]. + We are a [**DevOps Accelerator**][commercial_support]. We'll help you build your cloud infrastructure from the ground up so you can own it. Then we'll show you how to operate it and stick around for as long as you need us. @@ -174,51 +285,7 @@ We deliver 10x the value for a fraction of the cost of a full-time engineer. Our - **Code Reviews.** You'll receive constructive feedback on Pull Requests. - **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects. -## Slack Community - -Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. - -## Discourse Forums - -Participate in our [Discourse Forums][discourse]. Here you'll find answers to commonly asked questions. Most questions will be related to the enormous number of projects we support on our GitHub. Come here to collaborate on answers, find solutions, and get ideas about the products and services we value. It only takes a minute to get started! Just sign in with SSO using your GitHub account. - -## Newsletter - -Sign up for [our newsletter][newsletter] that covers everything on our technology radar. Receive updates on what we're up to on GitHub as well as awesome new projects we discover. - -## Office Hours - -[Join us every Wednesday via Zoom][office_hours] for our weekly "Lunch & Learn" sessions. It's **FREE** for everyone! - -[![zoom](https://img.cloudposse.com/fit-in/200x200/https://cloudposse.com/wp-content/uploads/2019/08/Powered-by-Zoom.png")][office_hours] - -## Contributing - -### Bug Reports & Feature Requests - -Please use the [issue tracker](https://github.com/cloudposse/github-action-atmos-affected-stacks/issues) to report any bugs or file feature requests. - -### Developing - -If you are interested in being a contributor and want to get involved in developing this project or [help out](https://cpco.io/help-out) with our other projects, we would love to hear from you! Shoot us an [email][email]. - -In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. - - 1. **Fork** the repo on GitHub - 2. **Clone** the project to your own machine - 3. **Commit** changes to your own branch - 4. **Push** your work back up to your fork - 5. Submit a **Pull Request** so that we can review your changes - -**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request! - - -## Copyright - -Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright) - - - +[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link] ## License [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) @@ -244,42 +311,11 @@ specific language governing permissions and limitations under the License. ``` - - - - - - - - ## Trademarks All other trademarks referenced herein are the property of their respective owners. - -## About - -This project is maintained and funded by [Cloud Posse, LLC][website]. Like it? Please let us know by [leaving a testimonial][testimonial]! - -[![Cloud Posse][logo]][website] - -We're a [DevOps Professional Services][hire] company based in Los Angeles, CA. We ❤️ [Open Source Software][we_love_open_source]. - -We offer [paid support][commercial_support] on all of our projects. - -Check out [our other projects][github], [follow us on twitter][twitter], [apply for a job][jobs], or [hire us][hire] to help with your cloud strategy and implementation. - - - -### Contributors - - -| [![Matt Calhoun][mcalhoun_avatar]][mcalhoun_homepage]
[Matt Calhoun][mcalhoun_homepage] | -|---| - - - [mcalhoun_homepage]: https://github.com/mcalhoun - [mcalhoun_avatar]: https://img.cloudposse.com/150x150/https://github.com/mcalhoun.png - +--- +Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright) [![README Footer][readme_footer_img]][readme_footer_link] [![Beacon][beacon]][website] @@ -290,12 +326,9 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=jobs [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=hire [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=slack - [linkedin]: https://cpco.io/linkedin?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=linkedin [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=twitter - [testimonial]: https://cpco.io/leave-testimonial?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=testimonial [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=office_hours [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=newsletter - [discourse]: https://ask.sweetops.com/?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=discourse [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=email [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=commercial_support [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=we_love_open_source @@ -306,11 +339,5 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=readme_footer_link [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-affected-stacks&utm_content=readme_commercial_support_link - [share_twitter]: https://twitter.com/intent/tweet/?text=github-action-atmos-affected&url=https://github.com/cloudposse/github-action-atmos-affected-stacks - [share_linkedin]: https://www.linkedin.com/shareArticle?mini=true&title=github-action-atmos-affected&url=https://github.com/cloudposse/github-action-atmos-affected-stacks - [share_reddit]: https://reddit.com/submit/?url=https://github.com/cloudposse/github-action-atmos-affected-stacks - [share_facebook]: https://facebook.com/sharer/sharer.php?u=https://github.com/cloudposse/github-action-atmos-affected-stacks - [share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/github-action-atmos-affected-stacks - [share_email]: mailto:?subject=github-action-atmos-affected&body=https://github.com/cloudposse/github-action-atmos-affected-stacks [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/github-action-atmos-affected-stacks?pixel&cs=github&cm=readme&an=github-action-atmos-affected-stacks diff --git a/README.yaml b/README.yaml index f4c6b2b..e509be0 100644 --- a/README.yaml +++ b/README.yaml @@ -43,6 +43,32 @@ references: [] # How to use this project usage: |- + + ### Config + + The action expects the atmos gitops configuration file to be present in the repository in `./.github/config/atmos-gitops.yaml`. + The config should have the following structure: + + ```yaml + atmos-version: 1.45.3 + atmos-config-path: ./rootfs/usr/local/etc/atmos/ + terraform-state-bucket: cptest-core-ue2-auto-gitops + terraform-state-table: cptest-core-ue2-auto-gitops + terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha + terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-version: 1.5.2 + aws-region: us-east-2 + enable-infracost: false + sort-by: .stack_slug + group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-") + ``` + + > [!IMPORTANT] + > **Please note!** the `terraform-state-*` parameters refer to the S3 Bucket and corresponding meta storage DynamoDB table used to store the Terraform Plan files, and not the "Terraform State". These parameters will be renamed in a subsequent release. + + ### Workflow example + ```yaml name: Pull Request on: @@ -56,12 +82,83 @@ usage: |- steps: - uses: actions/checkout@v3 - id: affected - uses: cloudposse/github-action-atmos-affected-stacks@feature/initial-implementation + uses: cloudposse/github-action-atmos-affected-stacks@v2 + with: + atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml + nested-matrices-count: 1 outputs: affected: ${{ steps.affected.outputs.affected }} matrix: ${{ steps.affected.outputs.matrix }} + + atmos-plan: + needs: ["atmos-affected"] + if: ${{ needs.atmos-affected.outputs.has-affected-stacks }} + name: ${{ matrix.stack_slug }} + runs-on: ['self-hosted'] + strategy: + max-parallel: 10 + fail-fast: false # Don't fail fast to avoid locking TF State + matrix: ${{ fromJson(needs.atmos-affected.outputs.stacks) }} + ## Avoid running the same stack in parallel mode (from different workflows) + concurrency: + group: ${{ matrix.stack_slug }} + cancel-in-progress: false + steps: + - name: Plan Atmos Component + uses: cloudposse/github-action-atmos-terraform-plan@v1 + with: + component: ${{ matrix.component }} + stack: ${{ matrix.stack }} + ``` + + ### Migrating from `v1` to `v2` + + `v2` moves most of the `inputs` to the Atmos GitOps config path `./.github/config/atmos-gitops.yaml`. Simply create this file, transfer your settings to it, then remove the corresponding arguments from your invocations of the `cloudposse/github-action-atmos-affected-stacks` action. + + | name | + |--------------------------| + | `atmos-version` | + | `atmos-config-path` | + | `terraform-state-bucket` | + | `terraform-state-table` | + | `terraform-state-role` | + | `terraform-plan-role` | + | `terraform-apply-role` | + | `terraform-version` | + | `aws-region` | + | `enable-infracost` | + + + If you want the same behavior in `v2` as in `v1` you should create config `./.github/config/atmos-gitops.yaml` with the same variables as in `v1` inputs. + + ```yaml + - name: Determine Affected Stacks + uses: cloudposse/github-action-atmos-affected-stacks@v2 + id: affected + with: + atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml + ``` + + Which would produce the same behavior as in `v1`, doing this: + + ```yaml + - name: Determine Affected Stacks + uses: cloudposse/github-action-atmos-affected-stacks@v1 + id: affected + with: + atmos-version: 1.45.3 + atmos-config-path: ./rootfs/usr/local/etc/atmos/ + terraform-state-bucket: cptest-core-ue2-auto-gitops + terraform-state-table: cptest-core-ue2-auto-gitops + terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha + terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops + terraform-version: 1.5.2 + aws-region: us-east-2 + enable-infracost: false ``` + include: - "docs/github-action.md" diff --git a/action.yml b/action.yml index 381e15d..3090921 100644 --- a/action.yml +++ b/action.yml @@ -1,29 +1,29 @@ name: "Atmos Affected Stacks" -description: "A GitHub Action to determine the affected stacks for a given pull request" +description: "A GitHub Action to determine the affected stacks between two git refs" author: hello@cloudposse.com branding: icon: "file" color: "white" inputs: + head-ref: + description: The head ref to checkout. If not provided, the head default branch is used. + required: false + default: ${{ github.sha }} default-branch: description: The default branch to use for the base ref. required: false default: ${{ github.event.repository.default_branch }} - head-ref: - description: The head ref to checkout. If not provided, the head default branch is used. + base-ref: + description: The base ref to checkout. If not provided, the head default branch is used. required: false install-atmos: description: Whether to install atmos required: false default: "true" - atmos-version: - description: The version of atmos to install if install-atmos is true + atmos-gitops-config-path: + description: The path to the atmos-gitops.yaml file required: false - default: "latest" - atmos-config-path: - description: The path to the atmos.yaml file - required: false - default: atmos.yaml + default: ./.github/config/atmos-gitops.yaml atmos-include-spacelift-admin-stacks: description: Whether to include the Spacelift admin stacks of affected stacks in the output required: false @@ -32,10 +32,6 @@ inputs: description: Whether to install terraform required: false default: "true" - terraform-version: - description: The version of terraform to install if install-terraform is true - required: false - default: "latest" install-jq: description: Whether to install jq required: false @@ -48,31 +44,45 @@ inputs: description: Whether to force the installation of jq required: false default: "true" + nested-matrices-count: + required: false + description: 'Number of nested matrices that should be returned as the output (from 1 to 3)' + default: "2" outputs: affected: description: The affected stacks value: ${{ steps.affected.outputs.affected }} has-affected-stacks: description: Whether there are affected stacks - value: ${{ steps.affected.outputs.affected != '[]' }} + value: ${{ steps.matrix.outputs.matrix != '{"include":[]}' }} matrix: - description: A matrix suitable for use for GitHub Actions of the affected stacks + description: The affected stacks as matrix structure suitable for extending matrix size workaround (see README) value: ${{ steps.matrix.outputs.matrix }} runs: using: "composite" steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.head-ref }} + + - name: config + uses: cloudposse/github-action-config-levels@nodejs20 + id: config + with: + output_properties: true + patterns: | + - ${{ inputs.atmos-gitops-config-path }} + - if: ${{ inputs.install-terraform == 'true' }} uses: hashicorp/setup-terraform@v2 with: - terraform_version: ${{ inputs.terraform-version }} + terraform_version: ${{ steps.config.outputs.terraform-version }} - if: ${{ inputs.install-atmos == 'true' }} uses: cloudposse/github-action-setup-atmos@v1.0.0 - env: - ATMOS_CLI_CONFIG_PATH: ${{inputs.atmos-config-path}} with: - atmos-version: ${{ inputs.atmos-version }} + atmos-version: ${{ steps.config.outputs.atmos-version }} install-wrapper: false - if: ${{ inputs.install-jq == 'true' }} @@ -91,28 +101,33 @@ runs: fetch-depth: 0 - name: checkout head ref - id: head-ref + id: base-ref shell: bash - run: git checkout ${{ inputs.head-ref }} + run: git checkout ${{ inputs.base-ref }} working-directory: main-branch + - name: Set vars + shell: bash + run: |- + echo "ATMOS_CLI_CONFIG_PATH=$(realpath ${{ steps.config.outputs.atmos-config-path }})" >> $GITHUB_ENV + echo "ATMOS_BASE_PATH=${{ github.workspace }}" >> $GITHUB_ENV + - name: atmos affected stacks id: affected shell: bash - env: - ATMOS_CLI_CONFIG_PATH: ${{inputs.atmos-config-path}} run: | if [[ "${{ inputs.atmos-include-spacelift-admin-stacks }}" == "true" ]]; then atmos describe affected --file affected-stacks.json --verbose=true --repo-path "$GITHUB_WORKSPACE/main-branch" --include-spacelift-admin-stacks=true else atmos describe affected --file affected-stacks.json --verbose=true --repo-path "$GITHUB_WORKSPACE/main-branch" fi - affected=$(jq -c '.' < affected-stacks.json) + affected=$(jq -c '.' affected-stacks.json) printf "%s" "affected=$affected" >> $GITHUB_OUTPUT - - name: build matrix + - uses: cloudposse/github-action-matrix-extended@v0 id: matrix - shell: bash - run: | - matrix=$(jq -c '{include:[.[]]}' < affected-stacks.json) - echo "matrix=$matrix" >> $GITHUB_OUTPUT + with: + matrix: affected-stacks.json + sort-by: ${{ steps.config.outputs.sort-by }} + group-by: ${{ steps.config.outputs.group-by }} + nested-matrices-count: ${{ inputs.nested-matrices-count }} diff --git a/docs/github-action.md b/docs/github-action.md index 748614b..cef9b2b 100644 --- a/docs/github-action.md +++ b/docs/github-action.md @@ -4,16 +4,17 @@ | Name | Description | Default | Required | |------|-------------|---------|----------| -| atmos-config-path | The path to the atmos.yaml file | atmos.yaml | false | -| atmos-version | The version of atmos to install if install-atmos is true | latest | false | +| atmos-gitops-config-path | The path to the atmos-gitops.yaml file | ./.github/config/atmos-gitops.yaml | false | +| atmos-include-spacelift-admin-stacks | Whether to include the Spacelift admin stacks of affected stacks in the output | false | false | +| base-ref | The base ref to checkout. If not provided, the head default branch is used. | N/A | false | | default-branch | The default branch to use for the base ref. | ${{ github.event.repository.default\_branch }} | false | -| head-ref | The head ref to checkout. If not provided, the head default branch is used. | N/A | false | +| head-ref | The head ref to checkout. If not provided, the head default branch is used. | ${{ github.sha }} | false | | install-atmos | Whether to install atmos | true | false | | install-jq | Whether to install jq | false | false | | install-terraform | Whether to install terraform | true | false | | jq-force | Whether to force the installation of jq | true | false | | jq-version | The version of jq to install if install-jq is true | 1.6 | false | -| terraform-version | The version of terraform to install if install-terraform is true | latest | false | +| nested-matrices-count | Number of nested matrices that should be returned as the output (from 1 to 3) | 2 | false | ## Outputs @@ -22,5 +23,5 @@ |------|-------------| | affected | The affected stacks | | has-affected-stacks | Whether there are affected stacks | -| matrix | A matrix suitable for use for GitHub Actions of the affected stacks | +| matrix | The affected stacks as matrix structure suitable for extending matrix size workaround (see README) | diff --git a/fixtures/atmos b/fixtures/atmos deleted file mode 100755 index a6d4b9d..0000000 --- a/fixtures/atmos +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -cat "${GITHUB_ACTION_PATH}/fixtures/mock-atmos-describe-affected.json" > affected-stacks.json diff --git a/fixtures/mock-atmos-describe-affected.json b/fixtures/mock-atmos-describe-affected.json deleted file mode 100644 index 5bb3470..0000000 --- a/fixtures/mock-atmos-describe-affected.json +++ /dev/null @@ -1,520 +0,0 @@ -[ - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-dns", - "stack_slug": "core-gbl-dns-datadog-integration", - "spacelift_stack": "core-gbl-dns-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-corp", - "stack_slug": "core-gbl-corp-datadog-integration", - "spacelift_stack": "core-gbl-corp-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-analytics", - "stack_slug": "core-gbl-analytics-datadog-integration", - "spacelift_stack": "core-gbl-analytics-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-security", - "stack_slug": "core-gbl-security-datadog-integration", - "affected": "component" - }, - { - "component": "eks/cluster", - "component_type": "terraform", - "component_path": "components/terraform/eks/cluster", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-eks-cluster", - "spacelift_stack": "core-ue2-auto-eks-cluster", - "affected": "component" - }, - { - "component": "eks/karpenter-provisioner", - "component_type": "terraform", - "component_path": "components/terraform/eks/karpenter-provisioner", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-eks-karpenter-provisioner", - "spacelift_stack": "core-ue2-auto-eks-karpenter-provisioner", - "affected": "stack.vars" - }, - { - "component": "ecr", - "component_type": "terraform", - "component_path": "components/terraform/ecr", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-ecr", - "spacelift_stack": "core-ue2-auto-ecr", - "affected": "stack.vars" - }, - { - "component": "eks/actions-runner-controller/public", - "component_type": "terraform", - "component_path": "components/terraform/eks/actions-runner-controller", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-eks-actions-runner-controller-public", - "spacelift_stack": "core-ue2-auto-eks-actions-runner-controller-public", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-acm", - "spacelift_stack": "core-ue2-auto-acm", - "affected": "component" - }, - { - "component": "eks/actions-runner-controller", - "component_type": "terraform", - "component_path": "components/terraform/eks/actions-runner-controller", - "stack": "core-ue2-auto", - "stack_slug": "core-ue2-auto-eks-actions-runner-controller", - "spacelift_stack": "core-ue2-auto-eks-actions-runner-controller", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "plat-gbl-sandbox", - "stack_slug": "plat-gbl-sandbox-datadog-integration", - "spacelift_stack": "plat-gbl-sandbox-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-public", - "stack_slug": "core-gbl-public-datadog-integration", - "spacelift_stack": "core-gbl-public-datadog-integration", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-prod", - "stack_slug": "plat-ue2-prod-acm", - "spacelift_stack": "plat-ue2-prod-acm", - "affected": "component" - }, - { - "component": "acm/hotfix", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-prod", - "stack_slug": "plat-ue2-prod-acm-hotfix", - "spacelift_stack": "plat-ue2-prod-acm-hotfix", - "affected": "component" - }, - { - "component": "acm/staging", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-prod", - "stack_slug": "plat-ue2-prod-acm-staging", - "spacelift_stack": "plat-ue2-prod-acm-staging", - "affected": "component" - }, - { - "component": "eks/karpenter-provisioner", - "component_type": "terraform", - "component_path": "components/terraform/eks/karpenter-provisioner", - "stack": "plat-ue2-prod", - "stack_slug": "plat-ue2-prod-eks-karpenter-provisioner", - "spacelift_stack": "plat-ue2-prod-eks-karpenter-provisioner", - "affected": "stack.vars" - }, - { - "component": "eks/cluster", - "component_type": "terraform", - "component_path": "components/terraform/eks/cluster", - "stack": "plat-ue2-prod", - "stack_slug": "plat-ue2-prod-eks-cluster", - "spacelift_stack": "plat-ue2-prod-eks-cluster", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-staging", - "stack_slug": "plat-ue2-staging-acm", - "spacelift_stack": "plat-ue2-staging-acm", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "plat-gbl-dev", - "stack_slug": "plat-gbl-dev-datadog-integration", - "spacelift_stack": "plat-gbl-dev-datadog-integration", - "affected": "component" - }, - { - "component": "account", - "component_type": "terraform", - "component_path": "components/terraform/account", - "stack": "core-gbl-root", - "stack_slug": "core-gbl-root-account", - "affected": "stack.vars" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-marketplace", - "stack_slug": "core-gbl-marketplace-datadog-integration", - "spacelift_stack": "core-gbl-marketplace-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-artifacts", - "stack_slug": "core-gbl-artifacts-datadog-integration", - "spacelift_stack": "core-gbl-artifacts-datadog-integration", - "affected": "component" - }, - { - "component": "acm/qa1", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-qa1", - "spacelift_stack": "plat-ue2-dev-acm-qa1", - "affected": "component" - }, - { - "component": "eks/cluster", - "component_type": "terraform", - "component_path": "components/terraform/eks/cluster", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-eks-cluster", - "spacelift_stack": "plat-ue2-dev-eks-cluster", - "affected": "component" - }, - { - "component": "acm/qa3", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-qa3", - "spacelift_stack": "plat-ue2-dev-acm-qa3", - "affected": "component" - }, - { - "component": "acm/qa2", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-qa2", - "spacelift_stack": "plat-ue2-dev-acm-qa2", - "affected": "component" - }, - { - "component": "acm/qa4", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-qa4", - "spacelift_stack": "plat-ue2-dev-acm-qa4", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm", - "spacelift_stack": "plat-ue2-dev-acm", - "affected": "component" - }, - { - "component": "acm/dev", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-dev", - "spacelift_stack": "plat-ue2-dev-acm-dev", - "affected": "component" - }, - { - "component": "acm/preview", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-acm-preview", - "spacelift_stack": "plat-ue2-dev-acm-preview", - "affected": "component" - }, - { - "component": "eks/karpenter-provisioner", - "component_type": "terraform", - "component_path": "components/terraform/eks/karpenter-provisioner", - "stack": "plat-ue2-dev", - "stack_slug": "plat-ue2-dev-eks-karpenter-provisioner", - "spacelift_stack": "plat-ue2-dev-eks-karpenter-provisioner", - "affected": "stack.vars" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-network", - "stack_slug": "core-gbl-network-datadog-integration", - "spacelift_stack": "core-gbl-network-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "plat-gbl-staging", - "stack_slug": "plat-gbl-staging-datadog-integration", - "spacelift_stack": "plat-gbl-staging-datadog-integration", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-gbl-staging", - "stack_slug": "plat-gbl-staging-acm", - "spacelift_stack": "plat-gbl-staging-acm", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-bar", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-bar", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-bar", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs/qa2", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa2", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa2", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-bar/dev", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-dev", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-dev", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-foo/qa1", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-qa1", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-qa1", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-bar/staging", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-staging", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-staging", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs/qa1", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa1", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa1", - "affected": "component" - }, - { - "component": "test-github-action", - "component_type": "terraform", - "component_path": "components/terraform/test-github-action", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-test-github-action", - "spacelift_stack": "plat-ue2-sandbox-test-github-action", - "affected": "component" - }, - { - "component": "acm", - "component_type": "terraform", - "component_path": "components/terraform/acm", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-acm", - "spacelift_stack": "plat-ue2-sandbox-acm", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-foo", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-foo", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-foo", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs/qa3", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa3", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa3", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs/dev", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-dev", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-dev", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-foo/dev", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-dev", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-dev", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs", - "affected": "component" - }, - { - "component": "vpc", - "component_type": "terraform", - "component_path": "components/terraform/vpc", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-vpc", - "spacelift_stack": "plat-ue2-sandbox-vpc", - "affected": "stack.vars" - }, - { - "component": "ecs-service/example-app-on-ecs/staging", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-staging", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-staging", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-bar/qa1", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-qa1", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-bar-qa1", - "affected": "component" - }, - { - "component": "ecs-service/example-app-on-ecs/qa4", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa4", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-app-on-ecs-qa4", - "affected": "component" - }, - { - "component": "ecs-service/example-monorepo-foo/staging", - "component_type": "terraform", - "component_path": "components/terraform/ecs-service", - "stack": "plat-ue2-sandbox", - "stack_slug": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-staging", - "spacelift_stack": "plat-ue2-sandbox-ecs-service-example-monorepo-foo-staging", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-ue2-root", - "stack_slug": "core-ue2-root-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-audit", - "stack_slug": "core-gbl-audit-datadog-integration", - "affected": "component" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "core-gbl-auto", - "stack_slug": "core-gbl-auto-datadog-integration", - "spacelift_stack": "core-gbl-auto-datadog-integration", - "affected": "component" - }, - { - "component": "infrastructure-cplive-plat", - "component_type": "terraform", - "component_path": "components/terraform/spacelift", - "stack": "core-gbl-auto", - "stack_slug": "core-gbl-auto-infrastructure-cplive-plat", - "spacelift_stack": "core-gbl-auto-infrastructure-cplive-plat", - "affected": "stack.vars" - }, - { - "component": "infrastructure-cplive-core", - "component_type": "terraform", - "component_path": "components/terraform/spacelift", - "stack": "core-gbl-auto", - "stack_slug": "core-gbl-auto-infrastructure-cplive-core", - "spacelift_stack": "core-gbl-auto-infrastructure-cplive-core", - "affected": "stack.vars" - }, - { - "component": "datadog-integration", - "component_type": "terraform", - "component_path": "components/terraform/datadog-integration", - "stack": "plat-gbl-prod", - "stack_slug": "plat-gbl-prod-datadog-integration", - "spacelift_stack": "plat-gbl-prod-datadog-integration", - "affected": "component" - } -] diff --git a/tests/atmos-gitops.yaml b/tests/atmos-gitops.yaml new file mode 100644 index 0000000..ad949b6 --- /dev/null +++ b/tests/atmos-gitops.yaml @@ -0,0 +1,11 @@ +atmos-version: 1.45.3 +atmos-config-path: ./rootfs/usr/local/etc/atmos/ +terraform-state-bucket: cptest-core-ue2-auto-gitops +terraform-state-table: cptest-core-ue2-auto-gitops +terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha +terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops +terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops +terraform-version: 1.5.2 +aws-region: us-east-2 +sort-by: .stack_slug +group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-") diff --git a/components/terraform/test/atmos.yaml b/tests/components/terraform/test/atmos.yaml similarity index 99% rename from components/terraform/test/atmos.yaml rename to tests/components/terraform/test/atmos.yaml index 498b8a3..e9c4330 100644 --- a/components/terraform/test/atmos.yaml +++ b/tests/components/terraform/test/atmos.yaml @@ -15,7 +15,7 @@ # are independent settings (supporting both absolute and relative paths). # If 'base_path' is provided, 'components.terraform.base_path', 'components.helmfile.base_path', 'stacks.base_path' and 'workflows.base_path' # are considered paths relative to 'base_path'. -base_path: "." +base_path: "./tests" components: terraform: diff --git a/components/terraform/test/main.tf b/tests/components/terraform/test/main.tf similarity index 100% rename from components/terraform/test/main.tf rename to tests/components/terraform/test/main.tf diff --git a/tests/fixtures/atmos b/tests/fixtures/atmos new file mode 100755 index 0000000..350da62 --- /dev/null +++ b/tests/fixtures/atmos @@ -0,0 +1,3 @@ +#!/bin/bash + +cat "${GITHUB_ACTION_PATH}/tests/fixtures/mock-atmos-describe-affected.json" > affected-stacks.json diff --git a/tests/fixtures/mock-atmos-describe-affected.json b/tests/fixtures/mock-atmos-describe-affected.json new file mode 100644 index 0000000..02b02d1 --- /dev/null +++ b/tests/fixtures/mock-atmos-describe-affected.json @@ -0,0 +1,54 @@ +[ + { + "component": "datadog-integration", + "component_type": "terraform", + "component_path": "components/terraform/datadog-integration", + "stack": "core-ue2-root", + "stack_slug": "core-ue2-root-datadog-integration", + "affected": "component" + }, + { + "component": "datadog-integration", + "component_type": "terraform", + "component_path": "components/terraform/datadog-integration", + "stack": "core-gbl-audit", + "stack_slug": "core-gbl-audit-datadog-integration", + "affected": "component" + }, + { + "component": "datadog-integration", + "component_type": "terraform", + "component_path": "components/terraform/datadog-integration", + "stack": "core-gbl-auto", + "stack_slug": "core-gbl-auto-datadog-integration", + "spacelift_stack": "core-gbl-auto-datadog-integration", + "affected": "component" + }, + { + "component": "infrastructure-cplive-plat", + "component_type": "terraform", + "component_path": "components/terraform/spacelift", + "stack": "core-gbl-auto", + "stack_slug": "core-gbl-auto-infrastructure-cplive-plat", + "spacelift_stack": "core-gbl-auto-infrastructure-cplive-plat", + "affected": "stack.vars" + }, + { + "component": "infrastructure-cplive-core", + "component_type": "terraform", + "component_path": "components/terraform/spacelift", + "stack": "core-gbl-auto", + "stack_slug": "core-gbl-auto-infrastructure-cplive-core", + "spacelift_stack": "core-gbl-auto-infrastructure-cplive-core", + "affected": "stack.vars" + }, + { + "component": "datadog-integration", + "component_type": "terraform", + "component_path": "components/terraform/datadog-integration", + "stack": "plat-gbl-prod", + "stack_slug": "plat-gbl-prod-datadog-integration", + "spacelift_stack": "plat-gbl-prod-datadog-integration", + "affected": "component" + } +] diff --git a/stacks/orgs/_defaults.yaml b/tests/stacks/orgs/_defaults.yaml similarity index 100% rename from stacks/orgs/_defaults.yaml rename to tests/stacks/orgs/_defaults.yaml diff --git a/stacks/orgs/test/test.yaml b/tests/stacks/orgs/test/test.yaml similarity index 100% rename from stacks/orgs/test/test.yaml rename to tests/stacks/orgs/test/test.yaml