Skip to content

workflow's optional ignore contract. The dry-run caller in ci.yaml #1101

Description

@github-actions

proves the input is accepted by GitHub's workflow schema; these assertions prove the value is

also forwarded to the shared scanner action when the real job runs.

# Guards the reusable TODO workflow's optional ignore contract. The dry-run caller in ci.yaml
# proves the input is accepted by GitHub's workflow schema; these assertions prove the value is
# also forwarded to the shared scanner action when the real job runs.

#!/usr/bin/env bash

# Guards the reusable TODO workflow's optional ignore contract. The dry-run caller in ci.yaml
# proves the input is accepted by GitHub's workflow schema; these assertions prove the value is
# also forwarded to the shared scanner action when the real job runs.

set -euo pipefail

workflow=".github/workflows/scan-for-todo-comments.yaml"
action="create-issues-from-todos/action.yaml"

fail() {
  echo "FAIL: $*" >&2
  exit 1
}

[[ -f "$workflow" ]] || fail "missing workflow: $workflow"
[[ -f "$action" ]] || fail "missing action: $action"

input_type="$(yq -r '.on.workflow_call.inputs.ignore.type // ""' "$workflow")"
[[ "$input_type" == "string" ]] ||
  fail "ignore must be a string workflow_call input; got: ${input_type:-<missing>}"

input_required="$(yq -r '.on.workflow_call.inputs.ignore.required // false' "$workflow")"
[[ "$input_required" == "false" ]] ||
  fail "ignore must remain optional; got required: $input_required"

input_default="$(yq -r '.on.workflow_call.inputs.ignore.default // ""' "$workflow")"
[[ -z "$input_default" ]] ||
  fail "ignore must default to an empty pattern; got: $input_default"

forwarded="$(yq -r \
  '.jobs.todos.steps[]
   | select(.uses == "./.devantler-tech-actions/create-issues-from-todos")
   | .with.ignore // ""' "$workflow")"
# shellcheck disable=SC2016 # GitHub expression compared literally.
[[ "$forwarded" == '${{ inputs.ignore }}' ]] ||
  fail "ignore must be forwarded unchanged to create-issues-from-todos; got: ${forwarded:-<missing>}"

action_required="$(yq -r '.inputs.ignore.required // false' "$action")"
[[ "$action_required" == "false" ]] ||
  fail "the scanner action's ignore input must remain optional; got required: $action_required"

action_default="$(yq -r '.inputs.ignore.default // ""' "$action")"
[[ -z "$action_default" ]] ||
  fail "the scanner action's ignore input must default to empty; got: $action_default"

action_env="$(yq -r \
  '.runs.steps[]
   | select(.name == "📝 Create issues from TODOs")
   | .env.INPUT_IGNORE // ""' "$action")"
# shellcheck disable=SC2016 # GitHub expression compared literally.
[[ "$action_env" == '${{ inputs.ignore }}' ]] ||
  fail "the scanner action must bind INPUT_IGNORE to inputs.ignore; got: ${action_env:-<missing>}"

action_run="$(yq -r \
  '.runs.steps[]
   | select(.name == "📝 Create issues from TODOs")
   | .run' "$action")"
grep -q -- '--env INPUT_IGNORE' <<<"$action_run" ||
  fail "the scanner container invocation must pass INPUT_IGNORE"

echo "scan-for-todo ignore input contract enforced ✅"

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions