Skip to content

Forward a submodules input to the caller checkout (#363) - #376

Open
leynos wants to merge 1 commit into
mainfrom
fix/mutation-cargo-submodules
Open

Forward a submodules input to the caller checkout (#363)#376
leynos wants to merge 1 commit into
mainfrom
fix/mutation-cargo-submodules

Conversation

@leynos

@leynos leynos commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

The mutation-cargo.yml reusable workflow checked out the caller repository
without submodules. Callers that vendor a build-graph dependency as a git
submodule (for example a Cargo path dependency under third_party/, as in
leynos/zamburak's third_party/full-monty) fail the unmutated baseline: the
submodule directory is empty, so cargo cannot read its Cargo.toml and the
run aborts in about a minute before any mutant is tested.

This adds a submodules input (default false, preserving current behaviour)
forwarded verbatim to actions/checkout's submodules input in every job
that checks out the caller repository — the detect job and every mutants
shard. Callers with submodule dependencies set submodules: recursive (or
true); the input is a no-op for repositories without a .gitmodules.

Closes #363.

Review walkthrough

  • .github/workflows/mutation-cargo.yml — new submodules input; both
    Checkout caller repository steps forward submodules: ${{ inputs.submodules }}.
  • docs/mutation-cargo-workflow.md — documents the input and when to set it.
  • workflow_scripts/tests/test_mutation_workflow_shape.py — new invariant
    test_caller_checkout_forwards_submodules_input pins that every caller
    checkout forwards the input.

Validation

  • pytest workflow_scripts/tests/test_mutation_workflow_shape.py — 5 passed.
  • ruff format --check / ruff check — clean; markdownlint / typos on the
    changed doc — clean.

…363)

Callers that vendor a build-graph dependency as a git submodule (for
example a Cargo path dependency under third_party/) fail the unmutated
baseline: the caller checkout defaults to no submodules, so the submodule
directory is empty and cargo cannot read its Cargo.toml before any mutant
runs.

Add a submodules input (default false, preserving current behaviour) and
forward it to actions/checkout in every job that checks out the caller
repository (detect and mutants, including shards). Document it in the caller
guide and pin a shape-test invariant that each caller checkout forwards the
input.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary

  • Added a configurable submodules input to the reusable Cargo mutation workflow, defaulting to false.
  • Forwarded the input to caller repository checkouts in the detect job and all mutants shards.
  • Documented support for true and recursive checkout modes for repositories using git submodules.
  • Added workflow-shape validation ensuring every caller checkout forwards the input.
  • Addresses issue #363 by allowing submodule-dependent baselines to build correctly.

Walkthrough

Changes

Mutation workflow submodules

Layer / File(s) Summary
Workflow input and checkout forwarding
.github/workflows/mutation-cargo.yml
Add the submodules input with a false default and forward it to caller-repository checkout steps in both jobs.
Usage documentation and shape validation
docs/mutation-cargo-workflow.md, workflow_scripts/tests/test_mutation_workflow_shape.py
Document recursive or enabled submodule checkout and validate forwarding on every caller checkout step.

Possibly related PRs

Suggested labels: Issue

Suggested reviewers: codescene-access

Poem

A submodule path now opens wide,
The checkout carries deps inside.
Detect and mutants follow through,
Shape tests guard the workflow too.
Cargo builds where roots once hid.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error The new workflow test only checks step names and with.submodules; it would miss a removed or renamed caller checkout and does not verify actions/checkout. Assert the exact caller-checkout job set (detect and mutants) and verify each step’s uses is actions/checkout@..., not just its name.
Developer Documentation ⚠️ Warning FAIL: the new submodules workflow input is documented only in caller-facing docs; docs/developers-guide.md and any ADR/design doc were not updated. Add a developers-guide entry or ADR/design note for the workflow input, and update the living execplan/progress section if this change belongs to that plan.
Testing (Unit And Behavioural) ⚠️ Warning The added test only parses YAML and checks a step field; it never runs the workflow or exercises a real submodule checkout boundary. Add an act-based or similar workflow test that runs mutation-cargo with submodules enabled and verifies the checkout/build path for a submodule-dependent repo.
✅ Passed checks (17 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the PR’s core change and links issue #363 as required.
Description check ✅ Passed The description is directly about forwarding a new submodules input and documenting it.
Linked Issues check ✅ Passed The PR satisfies #363 by adding a default-false submodules input, forwarding it to caller checkouts, and documenting it.
Out of Scope Changes check ✅ Passed The documentation and workflow-shape test are in scope for the submodules checkout fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
User-Facing Documentation ✅ Passed Document the new submodules input in the user-facing workflow guide, and keep the README signpost pointing to it.
Module-Level Documentation ✅ Passed The only changed module, workflow_scripts/tests/test_mutation_workflow_shape.py, already has a top-level docstring describing the workflow-shape tests and their role.
Testing (Property / Proof) ✅ Passed PASS: This adds a fixed workflow-shape invariant over two jobs, and the new deterministic test checks it exhaustively; property testing or proof is not warranted.
Testing (Compile-Time / Ui) ✅ Passed No Rust/TypeScript compile-time path exists here; the PR adds focused structural tests for the YAML workflow, which suits this text-based configuration.
Unit Architecture ✅ Passed PASS: submodules is surfaced as an explicit workflow input and forwarded at the checkout boundary; the new test is read-only YAML shape validation, not hidden orchestration.
Domain Architecture ✅ Passed Changes are confined to GitHub workflow, docs, and shape tests; no domain model or core business code is touched.
Observability ✅ Passed PASS: The change is documented, and existing checkout/cargo logs plus job-summary reporting already expose the submodule baseline failure path.
Security And Privacy ✅ Passed PASS: The change only forwards a caller-controlled checkout flag and documents it; no secrets, tokens, wider permissions, or unsafe sinks were introduced.
Performance And Resource Use ✅ Passed PASS: Only static workflow/docs/test changes; no new hot-path loops, unbounded collections, or repeated I/O. Extra submodule checkout is opt-in and bounded.
Concurrency And State ✅ Passed No shared mutable state, locking, async tasks, or ordering logic changed; the PR only forwards a checkout input and updates docs/tests.
Architectural Complexity And Maintainability ✅ Passed PASS: the PR adds one explicit workflow input, forwards it directly, and documents/tests it; no new layer, indirection, or extra abstraction appears.
Rust Compiler Lint Integrity ✅ Passed No Rust files changed in this PR; only workflow, docs, and Python test files were touched, so lint suppressions and clone hygiene are unaffected.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mutation-cargo-submodules

Comment @coderabbitai help to get the list of available commands.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@leynos
leynos marked this pull request as ready for review July 26, 2026 22:46

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No quality gates enabled for this code.

@buzzybee-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added the Issue label Jul 27, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/mutation-cargo.yml:
- Line 98: Update the checkout configuration associated with the submodules
input to support least-privilege credentials for private submodules, exposing
and forwarding an appropriate PAT or SSH-key input instead of relying solely on
the caller repository’s default github.token; if private access is intentionally
unsupported, document that only accessible or public submodules are supported.
- Around line 69-79: Quote the true/false examples in the submodules input
documentation while keeping its type as string and preserving recursive. Update
the description at .github/workflows/mutation-cargo.yml lines 69-79 and the
corresponding examples at docs/mutation-cargo-workflow.md lines 87-97 to use
'true' and 'false', with no other changes.

In `@workflow_scripts/tests/test_mutation_workflow_shape.py`:
- Around line 72-88: Strengthen the checkout validation in the test collecting
steps named by CALLER_CHECKOUT_STEP: require exactly the detect and mutants
jobs, and verify each matching step uses an actions/checkout action before
validating its with parameters. Preserve the existing submodules forwarding
assertion and diagnostics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 81bc616f-98a9-4084-bd67-ca82b7e82072

📥 Commits

Reviewing files that changed from the base of the PR and between 074f7d8 and e5c687d.

📒 Files selected for processing (3)
  • .github/workflows/mutation-cargo.yml
  • docs/mutation-cargo-workflow.md
  • workflow_scripts/tests/test_mutation_workflow_shape.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/polythene (auto-detected)

Comment on lines +69 to +79
submodules:
description: >-
How to check out the caller repository's git submodules,
forwarded verbatim to actions/checkout's `submodules` input:
`false` (default, no submodules), `true` (top-level only) or
`recursive`. Set this for callers that vendor a build-graph
dependency as a git submodule (e.g. a path dependency under
`third_party/`), whose directory must exist for the unmutated
baseline to build.
type: string
default: "false"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## Workflow input definition\n'
sed -n '1,140p' .github/workflows/mutation-cargo.yml

printf '\n## Docs excerpt\n'
sed -n '70,120p' docs/mutation-cargo-workflow.md

Repository: leynos/shared-actions

Length of output: 8160


🌐 Web query:

GitHub Actions reusable workflow inputs type string boolean YAML with: true quoted string workflow_call

💡 Result:

In GitHub Actions reusable workflows, the inputs context stores boolean values as actual booleans, unlike workflow_dispatch events which often treat them as strings [1][2]. Because of this, it is critical to use boolean literals (without quotes) when evaluating these inputs in conditions [1][3]. Key behaviors for boolean inputs in reusable workflows: 1. Usage in Conditions: Use the literal true or false rather than the string 'true' or 'false' [1][3]. For example: if: ${{ inputs.my-boolean == true }} or simply: if: ${{ inputs.my-boolean }} 2. Comparison Inconsistency: A common pitfall is that comparing a reusable workflow's boolean input against a string (e.g., inputs.my-boolean == 'true') will evaluate to false [3]. This contrasts with workflow_dispatch inputs, which are strings and require comparison against 'true' [1][3]. 3. Script Usage: When using a boolean input inside a run command, it may not behave as expected if directly interpolated. It is often safest to map the input to an environment variable, which will handle the conversion [4]: env: MY_BOOL: ${{ inputs.my-boolean }} run: echo $MY_BOOL 4. Defining Inputs: When defining inputs in on.workflow_call, specify the type: boolean [2]. If no default is provided, it defaults to false [2]. If you find yourself needing to handle both string and boolean types (e.g., if you are passing inputs from a source that is inconsistently typed), you can use a compound check: if: ${{ inputs.my-boolean == true || inputs.my-boolean == 'true' }} [5]

Citations:


🌐 Web query:

GitHub Actions workflow_call input type string boolean coercion reusable workflow caller passes true to string input

💡 Result:

In GitHub Actions, the handling of input types in reusable workflows (workflow_call) is strict and distinct from other event types like workflow_dispatch [1][2]. When defining an input with type: boolean in a reusable workflow, GitHub treats the value as an actual boolean type, not a string [1][2]. If a caller workflow attempts to pass a string "true" or "false" to an input defined as type: boolean in the reusable workflow, it will fail because the data types must strictly match [3][4]. Key considerations include: 1. Strict Typing: Reusable workflow inputs are strictly typed [3]. If you define an input as type: boolean, the caller must pass a boolean value [3]. If you define an input as type: string, the caller must pass a string value [3]. 2. Incompatibility with String Inputs: If your reusable workflow defines an input as type: string, it will not automatically coerce the string "true" into a boolean true [1]. You must treat it as a string within the workflow (e.g., by comparing it against the string literal 'true' in expressions: if: inputs.my-input == 'true') [5][1]. 3. Comparison Issues: There is a known inconsistency where comparing boolean inputs in workflow_call requires using the boolean literal true (e.g., if: inputs.my-bool == true), whereas workflow_dispatch often behaves as if inputs are strings [5][1]. If you are experiencing issues where a boolean input is not being evaluated correctly, ensure you are comparing it against the boolean primitive true or false rather than the string equivalents [5][1]. 4. Best Practice for Scripts: If you need to use a boolean input inside a run step, you may encounter issues where the boolean cannot be directly interpreted as a shell string [6]. A common workaround is to map the input to an environment variable in the job definition [6]: yaml jobs: my-job: runs-on: ubuntu-latest steps: - name: My step env: MY_BOOL: ${{ inputs.my-boolean-input }} run: echo "The value is $MY_BOOL" If you must pass a value that might vary in type, it is generally safer to define the input as type: string in your reusable workflow and perform manual validation or string comparisons within the called workflow [1].

Citations:


🌐 Web query:

site:docs.github.com reusable workflow input type string boolean caller YAML boolean string workflow_call

💡 Result:

In GitHub Actions, reusable workflows use the on.workflow_call.inputs keyword to define parameters passed from a caller workflow [1][2]. When defining these inputs, you must specify a type for each, which dictates the expected data type [1][3]. For on.workflow_call, the supported input types are boolean, number, and string [1][2]. To implement these in your YAML configuration: 1. In the Reusable Workflow: Define the inputs within the on.workflow_call block and specify the type [2][4]. yaml on: workflow_call: inputs: username: description: 'A username' type: string required: true dry-run: description: 'Perform a dry run' type: boolean default: false 2. In the Caller Workflow: Use the with keyword within your job to pass the values [2][4]. The data type of the value provided in the caller must match the type defined in the reusable workflow [2][4]. yaml jobs: call-workflow: uses: octo-org/example-repo/.github/workflows/reusable.yml@main with: username: 'octocat' dry-run: true If a default value is not provided in the reusable workflow, the system defaults to false for booleans, 0 for numbers, and "" (empty string) for strings [1][3]. Within the reusable workflow, you access these inputs using the inputs context (e.g., ${{ inputs.username }}) [1][3].

Citations:


🌐 Web query:

GitHub Actions workflow_call string input boolean literal true quoted default false type mismatch

💡 Result:

In GitHub Actions, the type of an input in a workflow_call must strictly match the type defined in the called (reusable) workflow [1][2]. If you define an input with type: boolean, GitHub expects a boolean value [1][3]. Providing a string literal like "true" or "false" from the caller workflow as an input can trigger a type mismatch error because the runner expects a boolean type [3]. Key Technical Details: 1. Strict Typing in workflow_call: Unlike workflow_dispatch, which treats all inputs as strings [4], workflow_call enforces the data type (boolean, number, or string) specified in the input definition [1][4]. 2. Avoiding the Mismatch: When passing a boolean value to a reusable workflow, ensure you pass the value as an expression that resolves to a boolean, not a quoted string [4]. - Correct usage in the caller workflow: with: my-input: ${{ true }} (or the result of a boolean expression) [5][4]. - Incorrect usage: with: my-input: "true" (this will be rejected as a string) [3]. 3. Handling Boolean Inputs in Scripts: Once passed, the boolean input in the called workflow is treated as an actual boolean [4]. If you need to use it in a shell script step (which expects strings), you must map it to an environment variable or convert it [6]. - Example fix for scripts: env: MY_BOOL: ${{ inputs.my-input }} run: echo "The value is $MY_BOOL" Comparison Note: Be aware that behavior can be inconsistent between workflow_call and workflow_dispatch events [5][4]. While workflow_call requires strict boolean types, workflow_dispatch often requires comparisons against string literals (e.g., inputs.x == 'true') [5][4]. If you find your reusable workflow is failing, verify that the caller is passing a native boolean type and that your expressions inside the called workflow compare against true/false literals rather than "true"/"false" strings [5][7][4].

Citations:


🌐 Web query:

GitHub workflow_call input type string accepts unquoted true false as strings or errors

💡 Result:

In GitHub Actions, the handling of boolean-like inputs in workflows—particularly when using workflow_call for reusable workflows—is frequently a source of confusion due to inconsistent typing across different event triggers [1][2]. When you define an input with type: string in a workflow_call schema, GitHub treats the input value strictly as a string [3]. If you attempt to pass unquoted values like true or false from a caller workflow to a string input, you may encounter configuration errors or unexpected behavior depending on how the YAML is parsed and subsequently evaluated by the workflow runner [4][1]. Key points regarding this behavior: 1. Inconsistent Type Evaluation: While workflow_call inputs defined as type: boolean are evaluated as actual boolean values in expressions (e.g., if: inputs.my-bool == true), inputs defined as type: string are always treated as strings [1][2]. If you pass a boolean value to a string input, the runner may struggle with type compatibility [4][5]. 2. Best Practices for Booleans: If you need to handle true/false logic, it is highly recommended to explicitly define the input type as type: boolean in your workflow_call definition [3]. 3. Debugging Comparisons: Because boolean inputs in workflow_call behave as actual booleans, comparing them to strings (e.g., inputs.my-bool == 'true') will often result in false [1]. Instead, compare them directly to boolean literals: if: ${{ inputs.my-bool == true }} 4. Working with Bash/Shell: If you must pass boolean values into a script (e.g., run:), the value may not be directly usable as a boolean depending on the context [6]. A reliable way to handle this is to pass the input through an environment variable in the job step, which converts the value to a string for the shell environment [6]: env: MY_BOOL: ${{ inputs.my-bool }} run: echo "The value is $MY_BOOL" If you are experiencing errors with unquoted true/false values, ensure that the input definition in the reusable workflow matches the intended data type and that your expressions in the caller workflow use the correct syntax for that type [3][1].

Citations:


🌐 Web query:

site:docs.github.com "workflow_call" "type: string" boolean input "true" string

💡 Result:

In GitHub Actions, when using the workflow_call trigger to define a reusable workflow, the type parameter for an input is mandatory and must be one of three values: string, boolean, or number [1]. To define these inputs in your reusable workflow, you use the on.workflow_call.inputs syntax [1]: on: workflow_call: inputs: my-string: type: string required: true my-boolean: type: boolean required: true my-number: type: number required: true When calling this workflow from another workflow, the values passed via the with keyword must match the data types specified [2][3]. If no default value is provided for an input, the default value defaults to an empty string ("") for string, false for boolean, and 0 for number [1].

Citations:


🌐 Web query:

site:docs.github.com actions workflow syntax reusable workflow inputs type string boolean number

💡 Result:

In GitHub Actions, reusable workflows (defined with the on.workflow_call trigger) allow you to define specific inputs that must be passed from a caller workflow [1][2]. For reusable workflows, the type of an input must be one of the following three values: boolean, number, or string [2]. When defining these inputs in your reusable workflow file, you must specify the type property [2]: on: workflow_call: inputs: username: description: 'A username' type: string required: true port: description: 'A port number' type: number default: 8080 enabled: description: 'Enable feature' type: boolean default: false Key syntax details include: 1. Type Enforcement: The type parameter is required for all inputs defined under on.workflow_call.inputs [2]. 2. Default Values: If no default is provided, the implicit default values are false for boolean, 0 for number, and "" (empty string) for string [2]. 3. Matching Types: When calling the workflow using the with keyword, the data type of the value provided in the caller workflow must match the type specified in the reusable workflow [1][3]. 4. Context Access: Inside the reusable workflow, these inputs are accessed using the inputs context (e.g., ${{ inputs.username }}) [4]. Note that while workflow_dispatch triggers also support input types, they include additional types like choice and environment, which are not available for reusable workflows [2].

Citations:


🌐 Web query:

GitHub Actions reusable workflow input type string coerce boolean YAML scalar to string docs

💡 Result:

In GitHub Actions, there is no explicit configuration to "coerce" a boolean YAML scalar to a string for inputs; however, the behavior of how boolean inputs are handled depends significantly on the workflow trigger event, often leading to confusion [1]. Key points regarding boolean input behavior: 1. Inconsistent Type Handling: Inputs defined as type: boolean act as actual boolean values within reusable workflows (workflow_call) but often behave as strings when they originate from workflow_dispatch events [2][1]. 2. Comparison Behavior: Because of this inconsistency, comparing a boolean input in a workflow_call must be done against a boolean literal (e.g., if: inputs.my-boolean == true), whereas doing the same for a workflow_dispatch event usually requires comparing against a string literal (e.g., if: inputs.my-boolean == 'true') [2][1]. 3. Passing Data: When passing inputs to a reusable workflow, the data type provided in the with: block must match the type defined in the called workflow [3]. If you are experiencing type mismatches when passing values between workflows, users often use the fromJSON function to force conversion or ensure the passed value matches the expected type [4][2]. 4. Custom Actions: Note that when writing custom actions (e.g., using @actions/core), inputs are always retrieved as strings by default [5][6]. The toolkit provides a specific function, core.getBooleanInput, to correctly handle boolean input parsing from YAML for custom actions [5]. If you find that a boolean is being treated as a string, you can generally normalize the comparison by evaluating it within an expression or using string-based comparison operators, such as testing the string value of the input: if: ${{ inputs.my-input == 'true' }} [2][1].

Citations:


🌐 Web query:

site:docs.github.com GitHub Actions workflow_call inputs type validation string boolean rejected

💡 Result:

When using the workflow_call trigger in GitHub Actions, inputs must be explicitly defined with a type [1][2]. The allowed values for this type are boolean, number, or string [1][2]. If a caller workflow provides an input value that does not match the type defined in the reusable workflow, the execution will typically fail because the data types must match [3][4][5]. There is no automatic type casting for mismatched inputs (e.g., passing a string "true" to an input typed as boolean will be rejected if it cannot be implicitly coerced or is strictly validated as a non-boolean type) [3][5]. Key technical details: - Definition: Within the reusable workflow, you must specify the type for each input under on.workflow_call.inputs.<input_id>.type [1][2]. - Validation: When an external workflow calls the reusable workflow using the with keyword, the data types of the passed values must strictly match the types specified in the called workflow [3][4]. - Errors: If the caller passes an input not defined in the reusable workflow, or if there is a fundamental mismatch in expectations, the workflow run will result in an error [1][2]. It is important to distinguish between reusable workflows (workflow_call) and composite actions. In reusable workflows, types are strictly enforced as described above [1][2]. In contrast, action metadata (used in composite or JavaScript actions) does not support a type parameter for inputs in the same way, and inputs there are generally treated as strings, with the action author responsible for any necessary validation or parsing within their code [6][7][8].

Citations:


🌐 Web query:

GitHub Actions workflow_call string input unquoted true false accepted as string

💡 Result:

In GitHub Actions, the handling of true and false values for workflow_call inputs depends on the type defined for that input [1][2]. When an input is explicitly defined with type: boolean in a reusable workflow, GitHub Actions treats the value as a formal boolean type, not a string [2][3]. Consequently, you should compare or evaluate these inputs against boolean values (true or false) rather than string literals ( 'true' or 'false') [2][3]. For example: if: ${{ inputs.my-boolean == true }} If an input is defined with type: string, the values true and false are treated as literal strings [2]. A common point of confusion arises because other workflow event types, such as workflow_dispatch, handle inputs differently—often treating them as strings regardless of their intended purpose [4][2]. Additionally, attempting to use a boolean input directly in a shell script can sometimes cause errors because shell environments generally only support strings [5]. To use a boolean input in a script, it is standard practice to map it to an environment variable [5]: jobs: my-job: runs-on: ubuntu-latest steps: - name: Use boolean env: MY_VAR: ${{ inputs.my-boolean }} run: echo "The value is $MY_VAR" If you are experiencing unexpected results with unquoted true/false values, ensure that the input type in your workflow_call definition matches the data type you are passing from the caller workflow [1]. Passing a string representation (e.g., 'true') into an input defined as type: boolean may cause a type mismatch error [6].

Citations:


🌐 Web query:

site:docs.github.com "workflow_call" "The data type of the input value must match the type declared in the called workflow"

💡 Result:

When using the workflow_call event in GitHub Actions to create a reusable workflow, you must explicitly define inputs and their corresponding data types [1][2]. The error stating that the data type of the input value must match the type declared in the called workflow occurs when there is a mismatch between the type provided by the caller workflow and the type specified in the called workflow's definition [3][4]. To resolve this issue, ensure the following requirements are met: 1. Defined Types: In the reusable (called) workflow, every input must have a type specified under the on.workflow_call.inputs.<input_id>.type key [1][4]. Valid types are string, number, or boolean [3][1]. 2. Consistent Values: The caller workflow must pass values that correspond to the type declared in the reusable workflow [3][5]. For example, if an input is defined as a boolean, the caller must pass a boolean value, not a string representation of one (e.g., use true instead of "true") [3][4]. If you define an input in the reusable workflow but fail to provide a value (and have not set a default), or provide a value that cannot be coerced into the required type, the workflow execution will fail [1][4]. Always check that the input definition in the reusable workflow aligns exactly with the values passed via the with keyword in the caller workflow [3][6].

Citations:


Quote the true/false examples. Keep submodules as a string so recursive still works, but change the workflow description and docs examples to 'true'/'false'; bare YAML booleans do not match this reusable-workflow input contract.

📍 Affects 2 files
  • .github/workflows/mutation-cargo.yml#L69-L79 (this comment)
  • docs/mutation-cargo-workflow.md#L87-L97
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/mutation-cargo.yml around lines 69 - 79, Quote the
true/false examples in the submodules input documentation while keeping its type
as string and preserving recursive. Update the description at
.github/workflows/mutation-cargo.yml lines 69-79 and the corresponding examples
at docs/mutation-cargo-workflow.md lines 87-97 to use 'true' and 'false', with
no other changes.

Source: MCP tools

uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
submodules: ${{ inputs.submodules }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔵 Trivial

Verify credentials for private submodules.

Forwarding submodules alone does not grant access to private secondary repositories. The checkouts expose no PAT or SSH-key input and rely on the default github.token, which is scoped to the caller repository. Expose least-privilege credentials or document that only accessible/public submodules are supported.

Also applies to: 198-198

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/mutation-cargo.yml at line 98, Update the checkout
configuration associated with the submodules input to support least-privilege
credentials for private submodules, exposing and forwarding an appropriate PAT
or SSH-key input instead of relying solely on the caller repository’s default
github.token; if private access is intentionally unsupported, document that only
accessible or public submodules are supported.

Source: MCP tools

Comment on lines +72 to +88
checkouts = [
(job_name, step)
for job_name, job in _jobs("mutation-cargo.yml").items()
for step in _steps(job)
if step.get("name") == CALLER_CHECKOUT_STEP
]
assert checkouts, "mutation-cargo.yml must check out the caller repository"
for job_name, step in checkouts:
params = step.get("with")
assert isinstance(params, dict), (
f"mutation-cargo.yml:{job_name} caller checkout must set `with`"
)
assert params.get("submodules") == SUBMODULES_EXPR, (
f"mutation-cargo.yml:{job_name} caller checkout must forward "
f"the submodules input (issue #363), got "
f"{params.get('submodules')!r}"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert every actual caller checkout.

The test only requires one step named Checkout caller repository and never checks uses. It passes if either detect or mutants loses its checkout, or if an unrelated action reuses that name. Assert the complete expected job set and validate the action identity.

     checkouts = [
         (job_name, step)
         for job_name, job in _jobs("mutation-cargo.yml").items()
         for step in _steps(job)
         if step.get("name") == CALLER_CHECKOUT_STEP
     ]
     assert checkouts, "mutation-cargo.yml must check out the caller repository"
+    expected_jobs = {"detect", "mutants"}
+    assert {job_name for job_name, _ in checkouts} == expected_jobs
     for job_name, step in checkouts:
+        uses = step.get("uses")
+        assert isinstance(uses, str) and uses.startswith("actions/checkout@"), (
+            f"mutation-cargo.yml:{job_name} caller checkout must use actions/checkout"
+        )
         params = step.get("with")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workflow_scripts/tests/test_mutation_workflow_shape.py` around lines 72 - 88,
Strengthen the checkout validation in the test collecting steps named by
CALLER_CHECKOUT_STEP: require exactly the detect and mutants jobs, and verify
each matching step uses an actions/checkout action before validating its with
parameters. Preserve the existing submodules forwarding assertion and
diagnostics.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mutation-cargo: caller checkout omits submodules, breaking builds with vendored git submodule deps

2 participants