Skip to content

ci: parameterized Pulumi deploy from stack-map (#682) #56

ci: parameterized Pulumi deploy from stack-map (#682)

ci: parameterized Pulumi deploy from stack-map (#682) #56

# Pulumi preview for DigitalOcean foundation (droplet, DNS, firewall, cloud-init).
#
# Required GitHub Actions secrets (Settings → Secrets and variables → Actions):
# DIGITALOCEAN_TOKEN — API token for @pulumi/digitalocean (read is enough for preview if DO allows it).
# PULUMI_BACKEND_URL — Same S3-compatible backend as other infra workflows (see scripts/infra/verify-backend.sh).
# Alternatively set PULUMI_ACCESS_TOKEN for app.pulumi.com if that is how the org logs in.
# PULUMI_CONFIG_PASSPHRASE — If stack config/secrets use passphrase encryption (align with infra-pulumi.yml).
#
# Repository variable (Settings → Secrets and variables → Actions → Variables), optional:
# PULUMI_FOUNDATION_STACK — Pulumi stack name for dev/pre-prod foundation (defaults to dev-staging if unset).
#
# Node: 20.x is the repo-standard infra toolchain (see infra/README.md "Tool versions"; root .nvmrc stays 16 for legacy app builds).
#
# This job does NOT use DOCKER_HOST, SSH to Swarm, or Tailscale — foundation talks only to the DigitalOcean API.
#
# Path filtering is done in the `filter` job, not under `pull_request.paths`, so workflow_dispatch runs are not tied
# to whether the current branch touched infra/foundation.
name: 'Infra foundation preview'
on:
workflow_dispatch:
pull_request:
concurrency:
group: foundation-preview-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
filter:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
foundation: ${{ steps.paths.outputs.foundation }}
steps:
- name: Check out the repo
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Detect foundation-related changes
uses: dorny/paths-filter@v4
id: paths
with:
base: ${{ github.event.pull_request.base.sha }}
ref: ${{ github.event.pull_request.head.sha }}
filters: |
foundation:
- 'infra/foundation/**'
- '.github/workflows/infra-foundation-preview.yml'
preview:
needs: filter
if: >-
always() &&
(
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository &&
needs.filter.outputs.foundation == 'true'
)
)
runs-on: ubuntu-latest
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
PULUMI_BACKEND_URL: ${{ secrets.PULUMI_BACKEND_URL }}
PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }}
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
PULUMI_FOUNDATION_STACK: ${{ vars.PULUMI_FOUNDATION_STACK || 'dev-staging' }}
steps:
- name: Check out the repo
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: npm
cache-dependency-path: infra/foundation/package-lock.json
- name: Install Pulumi CLI
shell: bash
run: |
# Keep version aligned with .github/reusable_workflows/pulumi_up/action.yaml and infra/README.md
curl -fsSL https://get.pulumi.com | sh -s -- --version 3.229.0
echo "${HOME}/.pulumi/bin" >> "${GITHUB_PATH}"
- name: Log in to Pulumi backend
shell: bash
working-directory: infra/foundation
run: |
set -euo pipefail
if [ -n "${PULUMI_BACKEND_URL:-}" ]; then
echo "Logging into Pulumi backend from PULUMI_BACKEND_URL"
pulumi login "${PULUMI_BACKEND_URL}"
elif [ -n "${PULUMI_ACCESS_TOKEN:-}" ]; then
echo "Using PULUMI_ACCESS_TOKEN for Pulumi Cloud"
pulumi login
else
echo "Error: Set PULUMI_BACKEND_URL or PULUMI_ACCESS_TOKEN for CI preview." >&2
exit 1
fi
- name: Install foundation dependencies
shell: bash
working-directory: infra/foundation
run: pulumi install
- name: Pulumi preview
shell: bash
working-directory: infra/foundation
run: |
set -euo pipefail
pulumi stack select "${PULUMI_FOUNDATION_STACK}"
pulumi preview --non-interactive