From 0030a01213db0da28615b2e8fc596470bdc8f1d1 Mon Sep 17 00:00:00 2001 From: Graham Savage Date: Mon, 29 Jun 2026 13:07:40 +0100 Subject: [PATCH 1/2] Expose KOSLI_FLOW and KOSLI_TRAIL as workflow outputs The base workflow computes the Kosli flow and trail used for attestations, but callers had no way to read them. Callers of the apply and plan workflows sometimes need to do further work after the call and must know where to send their own attestations. Emit KOSLI_FLOW and KOSLI_TRAIL as step outputs in base.yml, surface them as job and workflow_call outputs, and bubble them up through plan.yml and apply.yml. Also update apply.yml's reset-drift-detection job to consume these outputs instead of recalculating the flow and trail, removing the duplicated values. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/apply.yml | 11 +++++++++-- .github/workflows/base.yml | 16 ++++++++++++++++ .github/workflows/plan.yml | 7 +++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/workflows/apply.yml b/.github/workflows/apply.yml index 6833590..9d19cb7 100644 --- a/.github/workflows/apply.yml +++ b/.github/workflows/apply.yml @@ -65,6 +65,13 @@ on: kosli_github_token: description: "GitHub token used by `kosli attest pr github` to look up pull requests. Optional; when omitted the pull-request attestation step is skipped. Cannot be named `github_token` because that name is reserved by `workflow_call`." required: false + outputs: + kosli_flow: + description: "The Kosli flow name used for attestations." + value: ${{ jobs.apply.outputs.kosli_flow }} + kosli_trail: + description: "The Kosli trail name used for attestations." + value: ${{ jobs.apply.outputs.kosli_trail }} jobs: apply: @@ -103,8 +110,8 @@ jobs: KOSLI_ORG: ${{ inputs.kosli_org }} KOSLI_HOST: ${{ inputs.kosli_host }} KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }} - KOSLI_FLOW: terraform-apply-${{ inputs.environment }}-${{ github.event.repository.name }} - KOSLI_TRAIL: ${{ inputs.ref || github.event.pull_request.head.sha || github.sha }} + KOSLI_FLOW: ${{ needs.apply.outputs.kosli_flow }} + KOSLI_TRAIL: ${{ needs.apply.outputs.kosli_trail }} COMMIT_ARG: ${{ inputs.pass_commit_to_kosli_commands && format('--commit {0}', inputs.ref) || '' }} GH_TOKEN: ${{ secrets.kosli_github_token }} steps: diff --git a/.github/workflows/base.yml b/.github/workflows/base.yml index 37cfc6f..e3ac6ef 100644 --- a/.github/workflows/base.yml +++ b/.github/workflows/base.yml @@ -64,6 +64,12 @@ on: has_changes: description: "true if the plan contains changes, false if no changes" value: ${{ jobs.terraform.outputs.has_changes }} + kosli_flow: + description: "The Kosli flow name used for attestations." + value: ${{ jobs.terraform.outputs.kosli_flow }} + kosli_trail: + description: "The Kosli trail name used for attestations." + value: ${{ jobs.terraform.outputs.kosli_trail }} jobs: terraform: @@ -82,12 +88,22 @@ jobs: contents: write outputs: has_changes: ${{ steps.plan-summary.outputs.has_changes }} + kosli_flow: ${{ steps.kosli-outputs.outputs.kosli_flow }} + kosli_trail: ${{ steps.kosli-outputs.outputs.kosli_trail }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: ${{ inputs.github_repository_to_checkout }} ref: ${{ inputs.ref }} + - name: Export Kosli outputs + id: kosli-outputs + run: | + { + echo "kosli_flow=$KOSLI_FLOW" + echo "kosli_trail=$KOSLI_TRAIL" + } >> "$GITHUB_OUTPUT" + - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0 with: terraform_version: ${{ inputs.tf_version }} diff --git a/.github/workflows/plan.yml b/.github/workflows/plan.yml index a832540..32f9a38 100644 --- a/.github/workflows/plan.yml +++ b/.github/workflows/plan.yml @@ -50,6 +50,13 @@ on: kosli_api_token: description: "Kosli API token. Required when kosli_template_file is set." required: false + outputs: + kosli_flow: + description: "The Kosli flow name used for attestations." + value: ${{ jobs.plan.outputs.kosli_flow }} + kosli_trail: + description: "The Kosli trail name used for attestations." + value: ${{ jobs.plan.outputs.kosli_trail }} jobs: plan: From 3de0da31c82c9d89b2cc43f0865de9cd1ce809a8 Mon Sep 17 00:00:00 2001 From: Graham Savage Date: Mon, 29 Jun 2026 13:54:02 +0100 Subject: [PATCH 2/2] Quote-split COMMIT_ARG cleanly to silence actionlint SC2086 actionlint flagged the unquoted $COMMIT_ARG in several kosli `run:` steps. The word-splitting is intentional: COMMIT_ARG expands to either nothing or `--commit `, so quoting it would break the empty case. Mark the intent explicitly with a `# shellcheck disable=SC2086` directive, converting the affected single-line steps to block form. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/apply.yml | 9 +++++++-- .github/workflows/base.yml | 12 +++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/apply.yml b/.github/workflows/apply.yml index 9d19cb7..5446f22 100644 --- a/.github/workflows/apply.yml +++ b/.github/workflows/apply.yml @@ -165,15 +165,20 @@ jobs: - name: Kosli attest state file if: inputs.kosli_template_file != '' - run: kosli attest artifact "/tmp/${{ inputs.tf_state_file_name }}" --artifact-type file --name terraform-state $COMMIT_ARG + run: | + # shellcheck disable=SC2086 + kosli attest artifact "/tmp/${{ inputs.tf_state_file_name }}" --artifact-type file --name terraform-state $COMMIT_ARG - name: Kosli attest drift plan if: inputs.kosli_template_file != '' - run: kosli attest artifact /tmp/drift.plan.json --artifact-type file --name drift-plan $COMMIT_ARG + run: | + # shellcheck disable=SC2086 + kosli attest artifact /tmp/drift.plan.json --artifact-type file --name drift-plan $COMMIT_ARG - name: Kosli attest pull request if: inputs.kosli_template_file != '' && env.GH_TOKEN != '' run: | + # shellcheck disable=SC2086 kosli attest pr github \ --name pull-request \ --github-token "$GH_TOKEN" \ diff --git a/.github/workflows/base.yml b/.github/workflows/base.yml index e3ac6ef..72c7e44 100644 --- a/.github/workflows/base.yml +++ b/.github/workflows/base.yml @@ -175,11 +175,15 @@ jobs: - name: Kosli begin trail if: inputs.kosli_template_file != '' - run: kosli begin trail "$KOSLI_TRAIL" --template-file "${{ inputs.kosli_template_file }}" $COMMIT_ARG + run: | + # shellcheck disable=SC2086 + kosli begin trail "$KOSLI_TRAIL" --template-file "${{ inputs.kosli_template_file }}" $COMMIT_ARG - name: Kosli attest plan if: inputs.kosli_template_file != '' - run: kosli attest generic --name terraform-plan --attachments /tmp/${{ inputs.environment }}.plan.txt $COMMIT_ARG + run: | + # shellcheck disable=SC2086 + kosli attest generic --name terraform-plan --attachments /tmp/${{ inputs.environment }}.plan.txt $COMMIT_ARG - name: Apply if: inputs.tf_apply @@ -205,4 +209,6 @@ jobs: - name: Kosli attest apply if: inputs.tf_apply && inputs.kosli_template_file != '' - run: kosli attest generic --name terraform-apply --attachments /tmp/${{ inputs.environment }}.apply.txt $COMMIT_ARG + run: | + # shellcheck disable=SC2086 + kosli attest generic --name terraform-apply --attachments /tmp/${{ inputs.environment }}.apply.txt $COMMIT_ARG