# ACDL Reusable Deploy Workflow — Gitea Actions (dev environment) # # This reusable workflow implements the central deployment pipeline contract: # pipelines/deploy.yaml (validated against schemas/deploy-pipeline.schema.json) # # The same contract is implemented by .github/workflows/deploy.yml (GitHub # Actions, production). Both files must be byte-identical — the only # declared difference is the forge/runtime, not the stages or commands. # # Consumer repos invoke this workflow via a versioned tag (floating MAJOR + MINOR): # uses: acdl/.gitea/workflows/deploy.yml@v1.6 (Gitea) # uses: acdl/.github/workflows/deploy.yml@v1.6 (GitHub) # # Unversioned references (@main, bare) are discouraged — the consumer's setup # must be immutable + resilient. The versioned tag is the only immutability # lever (version constraints cannot be expressed inside the contract). # # What this workflow does: # 1. Checks out the consumer repo (the repo that invoked the workflow). # 2. Checks out the ACDL platform repo into the workspace (platform/). # This is the run-time fetch — consumers never clone the platform repo. # 3. Installs runtime deps: Python 3.12, Terraform 1.9.*, Checkov. # 4. Configures AWS auth (OIDC default; static-key override via secrets). # 5. Runs scripts/run_platform.sh against the consumer's contract path. # 6. Uploads artifacts (emitted Terraform, Checkov JSON, confidence JSON, # platform log) for auditability. # # Inputs: # contract — path to the consumer's contract YAML (default .acdl/contract.yaml) # mode — full | plan-only | check-only (default full; dev = full apply, # higher environments hold for HITL — the calling repo or the # forge environment gate enforces that) # # Auth (zero-trust default — see README.md#credentials--zero-trust): # OIDC federation is the default. permissions: id-token: write lets the # forge mint a short-lived STS token. The role-to-assume is scoped by the # consumer's repository identity (ABAC) — the workflow assumes the role # that matches repo:org/consumer-repo:ref:refs/heads/main, and the session # policy restricts view/update to resources tagged acdl:owner=. # # Override (where OIDC is unavailable, e.g. Gitea pending # go-gitea/gitea#36988): set ACDL_AWS_ACCESS_KEY_ID + ACDL_AWS_SECRET_ACCESS_KEY # as repository secrets. The platform-managed scheduled pipeline rotates # the key on a daily cadence. When .env.secrets is used locally instead, # rotating the key out of band is the consumer's responsibility. name: acdl-deploy on: workflow_call: inputs: contract: description: Path to the consumer contract YAML (in the consumer repo) type: string default: .acdl/contract.yaml mode: description: Pipeline mode — full (apply), plan-only, or check-only type: string default: full permissions: id-token: write contents: read jobs: deploy: name: Deploy runs-on: ubuntu-latest steps: - name: Check out consumer repo uses: actions/checkout@v4 - name: Check out ACDL platform repo uses: actions/checkout@v4 with: repository: acdl/acdl path: platform ref: v1.6 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install runtime dependencies run: | pip install --break-system-packages jsonschema pyyaml boto3 pip install --break-system-packages "checkov>=3.2,<4" - name: Install Terraform 1.9.* run: | wget -qO- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg echo "deb [signed-by=/usr/share/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt-get update && sudo apt-get install -y terraform=1.9.* - name: Configure AWS credentials (OIDC default) uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::${{ secrets.ACDL_AWS_ACCOUNT_ID }}:role/acdl-deploy-${{ github.repository_id }} aws-region: us-east-1 env: ACDL_AWS_ACCESS_KEY_ID: ${{ secrets.ACDL_AWS_ACCESS_KEY_ID }} ACDL_AWS_SECRET_ACCESS_KEY: ${{ secrets.ACDL_AWS_SECRET_ACCESS_KEY }} - name: Run the platform pipeline working-directory: ${{ github.workspace }} run: | MODE_FLAG="" case "${{ inputs.mode }}" in full) MODE_FLAG="" ;; plan-only) MODE_FLAG="--plan-only" ;; check-only) MODE_FLAG="--check-only" ;; *) echo "Unknown mode: ${{ inputs.mode }}"; exit 1 ;; esac bash platform/scripts/run_platform.sh $MODE_FLAG "${{ inputs.contract }}" - name: Upload emitted Terraform uses: actions/upload-artifact@v4 with: name: acdl-terraform path: platform/terraform/spike/*.tf if-no-files-found: warn - name: Upload platform log uses: actions/upload-artifact@v4 with: name: acdl-platform-log path: platform/logs/ if-no-files-found: warn