diff --git a/template/.github/actions/update-devcontainer-hash/action.yml.jinja-base b/template/.github/actions/update-devcontainer-hash/action.yml.jinja-base index 9aa0fca3..cdb24e79 100644 --- a/template/.github/actions/update-devcontainer-hash/action.yml.jinja-base +++ b/template/.github/actions/update-devcontainer-hash/action.yml.jinja-base @@ -5,9 +5,6 @@ inputs: description: 'Branch to checkout and update' required: true -permissions: - contents: write - outputs: new-sha: description: 'The SHA of the branch tip after update' diff --git a/template/template/.github/actions/check-skip-duplicates/action.yml.jinja-base b/template/template/.github/actions/check-skip-duplicates/action.yml.jinja-base new file mode 100644 index 00000000..27fa6792 --- /dev/null +++ b/template/template/.github/actions/check-skip-duplicates/action.yml.jinja-base @@ -0,0 +1,44 @@ +{% raw %}name: Check Skip Duplicates +description: 'Check that will output a variable to allow you to skip duplicate runs. Example: If you have both push and pull_request triggers enabled and you dont want to run 2 jobs for the same commit if a PR is already open you can add this to your jobs to skip that extra execution.' + +outputs: + should-run: + description: 'Flag that determines if this execution should run or not' + value: ${{ steps.check.outputs.should_run }} + +runs: + using: composite + steps: + - name: Check if push has associated open PR + id: check + env: + GH_TOKEN: ${{ github.token }} + REF_NAME: ${{ github.ref_name }} + REPO_NAME: ${{ github.repository }} + EVENT_NAME: ${{ github.event_name }} + shell: bash + run: | + # For non-push events, always run + if [ "$EVENT_NAME" != "push" ]; then + echo "should_run=true" >> $GITHUB_OUTPUT + echo "Event is $EVENT_NAME, will run CI" + exit 0 + fi + + # For push events, check if there's an open PR for this branch + pr_json=$(gh pr list \ + --repo "$REPO_NAME" \ + --head "$REF_NAME" \ + --state open \ + --json number \ + --limit 1) + + pr_number=$(echo "$pr_json" | jq -r '.[0].number // ""') + + if [ -n "$pr_number" ]; then + echo "should_run=false" >> $GITHUB_OUTPUT + echo "Push to branch with open PR #$pr_number detected, skipping (PR event will run CI)" + else + echo "should_run=true" >> $GITHUB_OUTPUT + echo "Push to branch without open PR, will run CI" + fi{% endraw %} diff --git a/template/template/.github/actions/{% if template_uses_pulumi %}pulumi_ephemeral_deploy{% endif %}/action.yml.jinja-base b/template/template/.github/actions/{% if template_uses_pulumi %}pulumi_ephemeral_deploy{% endif %}/action.yml.jinja-base index f7e53678..c46df7e4 100644 --- a/template/template/.github/actions/{% if template_uses_pulumi %}pulumi_ephemeral_deploy{% endif %}/action.yml.jinja-base +++ b/template/template/.github/actions/{% if template_uses_pulumi %}pulumi_ephemeral_deploy{% endif %}/action.yml.jinja-base @@ -41,6 +41,11 @@ inputs: default: true required: false description: Whether or not to install the Pulumi CLI + show-preview-comment-on-pr: + type: boolean + default: false + required: false + description: Whether or not to add a comment on to the PR with the pulumi preview details. @@ -74,6 +79,23 @@ runs: aws-region: ${{ inputs.aws-region }} - name: Run CLI - working-directory: ${{ github.workspace }}/${{ inputs.project-dir }} - run: uv run python -m ${{ inputs.deploy-script-module-name }}.${{ inputs.deploy-script-name }} --stack=${{ inputs.stack-name }} ${{ inputs.cli-action }} - shell: bash{% endraw %} + # apparently getting the stdout is nigh impossible in GHA, so this action helps + uses: mathiasvr/command-output@34408ea3d0528273faff3d9e201761ae96106cd0 # ratchet:mathiasvr/command-output@v2.0.0 + id: pulumi-run + with: + # can't use working-directory with this action, so specifying it in the uv command + run: uv --directory ${{ github.workspace }}/${{ inputs.project-dir }} run python -m ${{ inputs.deploy-script-module-name }}.${{ inputs.deploy-script-name }} --stack=${{ inputs.stack-name }} ${{ inputs.cli-action }} + shell: bash + + - name: Comment the Preview on the Pull Request + if: ${{ inputs.show-preview-comment-on-pr == 'true' }} + # pin this sha (v3.0.1) for extra security since this action has some permissions to write to the pull request comments + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b + with: + message: | + :eyes: **Pulumi Preview for ${{ inputs.deploy-script-module-name }}:** :eyes: + + ```bash + ${{ steps.pulumi-run.outputs.stdout }} + ``` + comment-tag: previewonpr-${{ inputs.deploy-script-module-name }}{% endraw %} diff --git a/template/template/.github/workflows/{% if template_uses_pulumi %}pulumi-aws.yml{% endif %}.jinja-base b/template/template/.github/workflows/{% if template_uses_pulumi %}pulumi-aws.yml{% endif %}.jinja-base index 9356f7be..b924c600 100644 --- a/template/template/.github/workflows/{% if template_uses_pulumi %}pulumi-aws.yml{% endif %}.jinja-base +++ b/template/template/.github/workflows/{% if template_uses_pulumi %}pulumi-aws.yml{% endif %}.jinja-base @@ -86,6 +86,11 @@ on: required: false default: '' type: string + SHOW_PREVIEW_COMMENT_ON_PR: + description: 'Shows the pulumi preview details on the PR, note this is dependent on the pull_request event' + required: false + default: false + type: boolean secrets: iac-github-api-tokens: description: 'API tokens to use for Github IaC deployment when not using AWS Secrets Manager' @@ -99,6 +104,7 @@ env: permissions: id-token: write # needed to assume OIDC roles (e.g. for downloading from CodeArtifact) contents: write # needed for mutex + pull-requests: write # needed to post the preview on the PR as a comment jobs: pulumi: @@ -154,6 +160,7 @@ jobs: deploy-script-name: ${{ inputs.DEPLOY_SCRIPT_NAME }} aws-region: ${{ inputs.AWS_REGION }} aws-account-id: ${{ inputs.AWS_ACCOUNT_ID }} + show-preview-comment-on-pr: ${{ inputs.SHOW_PREVIEW_COMMENT_ON_PR }} timeout-minutes: 5 # apparently timeout-minutes only accepts literal values, it cannot evaluate expressions (e.g. workflow inputs) - name: Refresh