Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: E2E Test
run-name: 'e2e: test-${{ github.run_id }}'

on:
workflow_dispatch:

permissions:
id-token: write
contents: read
pull-requests: write
actions: read

jobs:
init:
uses: ./.github/workflows/pulumi.yml
with:
cmd: init
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets-provider: ${{ vars.GCP_KMS_KEY }}
secrets: inherit

preview-create:
needs: init
uses: ./.github/workflows/pulumi.yml
with:
cmd: preview
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit

up:
needs: preview-create
uses: ./.github/workflows/pulumi.yml
with:
cmd: up
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit

preview-nop:
needs: up
uses: ./.github/workflows/pulumi.yml
with:
cmd: preview
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit

destroy:
needs: [up, preview-nop]
if: always() && needs.up.result == 'success'
uses: ./.github/workflows/pulumi.yml
with:
cmd: destroy
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit

preview-recreate:
needs: destroy
if: always() && needs.destroy.result == 'success'
uses: ./.github/workflows/pulumi.yml
with:
cmd: preview
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit

stack-rm:
needs: [destroy, preview-recreate]
if: always() && needs.destroy.result == 'success'
uses: ./.github/workflows/pulumi.yml
with:
cmd: stack-rm
stack: test-${{ github.run_id }}
project: e2e
working-directory: test
comment-on-pr: false
secrets: inherit
30 changes: 28 additions & 2 deletions .github/workflows/pulumi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
workflow_call:
inputs:
cmd:
description: 'Pulumi command (preview, up, refresh)'
description: 'Pulumi command (preview, up, refresh, destroy, init, stack-rm)'
required: true
type: string
stack:
Expand Down Expand Up @@ -53,10 +53,17 @@ on:
required: false
default: 'a2b415984ed69668323572cc4df274992932c304'
type: string
secrets-provider:
description: 'Secrets provider for stack init (e.g. "gcpkms://projects/.../cryptoKeys/...")'
required: false
type: string
secrets:
PULUMI_ACCESS_TOKEN:
description: 'Pulumi Cloud access token (if using Pulumi Cloud backend)'
required: false
PULUMI_CONFIG_PASSPHRASE:
description: 'Passphrase for stack encryption (leave unset for empty passphrase on self-managed backends)'
required: false

# Pulumi fork with --patch flag for GitHub-compatible diff output
# https://github.com/Open-Athena/pulumi/commits/patch
Expand Down Expand Up @@ -162,9 +169,23 @@ jobs:
- name: Run Pulumi ${{ inputs.cmd }}
id: pulumi
working-directory: ${{ inputs.working-directory }}
env:
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
run: |
set -o pipefail

case "${{ inputs.cmd }}" in
init)
pulumi stack init ${{ inputs.stack }} \
${{ inputs.secrets-provider && format('--secrets-provider="{0}"', inputs.secrets-provider) || '' }}
exit 0
;;
stack-rm)
pulumi stack rm ${{ inputs.stack }} --yes --force
exit 0
Comment on lines +180 to +185

Copilot AI Mar 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init and stack-rm exit before writing pulumi-output.txt, so the “Summary and PR comment” step will always be skipped for these commands. If these commands are intended to be first-class workflow commands, consider capturing their output to pulumi-output.txt (and letting the summary step run) to aid debugging/visibility.

Suggested change
${{ inputs.secrets-provider && format('--secrets-provider="{0}"', inputs.secrets-provider) || '' }}
exit 0
;;
stack-rm)
pulumi stack rm ${{ inputs.stack }} --yes --force
exit 0
${{ inputs.secrets-provider && format('--secrets-provider="{0}"', inputs.secrets-provider) || '' }} \
2>&1 | tee pulumi-output.txt
exit ${PIPESTATUS[0]}
;;
stack-rm)
pulumi stack rm ${{ inputs.stack }} --yes --force \
2>&1 | tee pulumi-output.txt
exit ${PIPESTATUS[0]}

Copilot uses AI. Check for mistakes.
;;
esac

pulumi stack select ${{ inputs.stack }}

# Remove profile if set (use env vars instead)
Expand All @@ -180,6 +201,9 @@ jobs:
refresh)
pulumi refresh --yes --non-interactive 2>&1 | tee pulumi-output.txt
;;
destroy)
pulumi destroy --yes --non-interactive 2>&1 | tee pulumi-output.txt
;;
*)
echo "::error::Unknown command: ${{ inputs.cmd }}"
exit 1
Expand All @@ -204,7 +228,7 @@ jobs:
PREFIX="${{ inputs.project && format('{0}: ', inputs.project) || '' }}"

# Dynamic fence length: one longer than any backtick run in content (min 3)
MAX=$(grep -oE '\`+' pulumi-output.txt | awk '{print length}' | sort -rn | head -1)
MAX=$(grep -oE '[`]+' pulumi-output.txt | awk '{print length}' | sort -rn | head -1)
FENCE=$(printf '`%.0s' $(seq 1 $(( ${MAX:-0} > 2 ? MAX + 1 : 3 ))))

# Build shared output body
Expand Down Expand Up @@ -259,6 +283,8 @@ jobs:
- name: Export outputs
if: inputs.cmd == 'up'
working-directory: ${{ inputs.working-directory }}
env:
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
run: |
echo "### Pulumi Stack Outputs" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Test
run-name: 'test: pulumi ${{ inputs.cmd }}'

on:
workflow_dispatch:
inputs:
cmd:
description: 'Pulumi command'
required: true
default: 'preview'
type: choice
options:
- preview
- up
- refresh
- destroy
- init

permissions:
id-token: write
contents: read
pull-requests: write
actions: read

jobs:
pulumi:
uses: ./.github/workflows/pulumi.yml
with:
cmd: ${{ inputs.cmd }}
stack: test
project: pulumi-v1-test
working-directory: test
secrets: inherit
2 changes: 2 additions & 0 deletions test/Pulumi.test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config:
aws:region: us-east-1
5 changes: 5 additions & 0 deletions test/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: pulumi-v1-test
description: Test stack for the pulumi-v1 reusable workflow
runtime: python
backend:
url: gs://oa-pulumi
Comment on lines +4 to +5

Copilot AI Mar 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project hardcodes a GCS backend (gs://oa-pulumi). That makes the new test/ stack and the reusable workflows non-portable unless that bucket + GCP auth vars exist. Consider making the backend configurable (e.g., omit it here and rely on pulumi login/env in CI, or document the required backend setup for contributors).

Suggested change
backend:
url: gs://oa-pulumi

Copilot uses AI. Check for mistakes.
41 changes: 41 additions & 0 deletions test/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Test stack for the pulumi-v1 reusable workflow.

Creates lightweight, free AWS resources to exercise `pulumi preview --patch`
diff output, job summaries, and PR comments.
"""
import pulumi
import pulumi_aws as aws
import pulumi_tls as tls

config = pulumi.Config()

Copilot AI Mar 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config = pulumi.Config() is declared but never used in this stack; if it’s not needed, remove it to avoid unused-variable lint noise, or use it to read required test configuration.

Suggested change
config = pulumi.Config()

Copilot uses AI. Check for mistakes.
env = pulumi.get_stack()

# EC2 Key Pair (via TLS-generated key)
key = tls.PrivateKey("test-key", algorithm="ED25519")
key_pair = aws.ec2.KeyPair("test-key-pair",
key_name=f"pulumi-v1-test-{env}",
public_key=key.public_key_openssh,
)

# IAM Role (no trust policy; just exists for diff testing)

Copilot AI Mar 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the IAM role has “no trust policy”, but assume_role_policy is explicitly set. Please either adjust the comment to match the code, or change the role definition to align with the intent (e.g., a minimal/valid trust policy for a dummy role).

Suggested change
# IAM Role (no trust policy; just exists for diff testing)
# IAM Role (deny-all trust policy; just exists for diff testing)

Copilot uses AI. Check for mistakes.
role = aws.iam.Role("test-role",
name=f"pulumi-v1-test-{env}",
assume_role_policy="""{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}""",
)

# CloudWatch Log Group
log_group = aws.cloudwatch.LogGroup("test-log-group",
name=f"/pulumi-v1/test/{env}",
retention_in_days=1,
)

pulumi.export("key_pair_name", key_pair.key_name)
pulumi.export("role_arn", role.arn)
pulumi.export("log_group_name", log_group.name)
3 changes: 3 additions & 0 deletions test/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pulumi>=3.0.0
pulumi-aws>=6.0.0
pulumi-tls>=5.0.0
Loading