Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions actions/setup/js/check_workflow_timestamp_api.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
/// <reference types="@actions/github-script" />

/**
* Check workflow lock file integrity using frontmatter hash validation.
* Check for a stale workflow lock file using frontmatter hash comparison.
* This script verifies that the stored frontmatter hash in the lock file
* matches the recomputed hash from the source .md file, regardless of
* commit timestamps.
* matches the recomputed hash from the source .md file, detecting cases where
* the workflow was edited without recompiling the lock file. It does not
* provide tamper protection — use code review to guard against intentional
* modifications.
Comment on lines +8 to +10
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The docstring says it detects cases where “the workflow was edited without recompiling the lock file,” but the comparison is based on the frontmatter hash (not the full markdown workflow content). To avoid implying broader coverage than implemented, consider rephrasing to “frontmatter (and imported frontmatter) was edited without recompiling.”

Suggested change
* the workflow was edited without recompiling the lock file. It does not
* provide tamper protection use code review to guard against intentional
* modifications.
* frontmatter (and imported frontmatter) was edited without recompiling the
* lock file. It does not provide tamper protection use code review to guard
* against intentional modifications.

Copilot uses AI. Check for mistakes.
*
* Supports both same-repo and cross-repo reusable workflow scenarios:
* - Primary: GitHub API (uses GITHUB_WORKFLOW_REF to identify source repo)
Expand Down Expand Up @@ -33,7 +35,7 @@ async function main() {
const workflowMdPath = `.github/workflows/${workflowBasename}.md`;
const lockFilePath = `.github/workflows/${workflowFile}`;

core.info(`Checking workflow lock file integrity using frontmatter hash:`);
core.info(`Checking for stale lock file using frontmatter hash:`);
core.info(` Source: ${workflowMdPath}`);
core.info(` Lock file: ${lockFilePath}`);

Expand Down Expand Up @@ -193,11 +195,11 @@ async function main() {
if (!hashComparison) {
// Could not compute hash - be conservative and fail
core.warning("Could not compare frontmatter hashes - assuming lock file is outdated");
const warningMessage = `Lock file '${lockFilePath}' integrity check failed! Could not verify frontmatter hash for '${workflowMdPath}'. Run 'gh aw compile' to regenerate the lock file.`;
const warningMessage = `Lock file '${lockFilePath}' is outdated or unverifiable! Could not verify frontmatter hash for '${workflowMdPath}'. Run 'gh aw compile' to regenerate the lock file.`;

Comment on lines 195 to 199
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The failure/warning message text here has changed (no longer includes "integrity check failed"), but the unit tests still assert on the old substring (e.g., actions/setup/js/check_workflow_timestamp_api.test.cjs lines ~237, ~248, ~350, etc.). Please update those expectations to match the new wording, otherwise CI will fail.

See below for a potential fix:

    const warningMessage = `Lock file '${lockFilePath}' is outdated or unverifiable! Frontmatter integrity check failed for '${workflowMdPath}'. Run 'gh aw compile' to regenerate the lock file.`;

    let summary = core.summary
      .addRaw("### ⚠️ Workflow Lock File Warning\n\n")
      .addRaw("**WARNING**: Could not verify whether lock file is up to date. Frontmatter integrity check failed.\n\n")

Copilot uses AI. Check for mistakes.
let summary = core.summary
.addRaw("### ⚠️ Workflow Lock File Warning\n\n")
.addRaw("**WARNING**: Lock file integrity check failed. Could not verify frontmatter hash.\n\n")
.addRaw("**WARNING**: Could not verify whether lock file is up to date. Frontmatter hash check failed.\n\n")
.addRaw("**Files:**\n")
.addRaw(`- Source: \`${workflowMdPath}\`\n`)
.addRaw(`- Lock: \`${lockFilePath}\`\n\n`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ This document specifies the algorithm for computing a deterministic hash of agen
## Purpose

The frontmatter hash provides:
1. **Change detection**: Verify that workflow configuration has not changed between compilation and execution
1. **Stale lock detection**: Identify when the compiled lock file is out of sync with the source workflow (e.g. after editing the `.md` file without recompiling)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This purpose statement implies that any edit to the .md workflow file will be detected as a stale lock, but the spec explicitly excludes markdown body content from the hash (see the Excluded Fields list). Consider narrowing the wording to “after editing the workflow frontmatter (or imported frontmatter) without recompiling” to avoid overstating what the hash detects.

Suggested change
1. **Stale lock detection**: Identify when the compiled lock file is out of sync with the source workflow (e.g. after editing the `.md` file without recompiling)
1. **Stale lock detection**: Identify when the compiled lock file is out of sync with the source workflow (e.g. after editing the workflow frontmatter or imported frontmatter without recompiling)

Copilot uses AI. Check for mistakes.
2. **Reproducibility**: Ensure identical configurations produce identical hashes across languages (Go and JavaScript)
3. **Security**: Detect unauthorized modifications to workflow frontmatter
3. **Change detection**: Verify that workflow configuration has not changed between compilation and execution

## Hash Algorithm

Expand Down Expand Up @@ -196,8 +196,8 @@ Both Go and JavaScript implementations MUST:
## Security Considerations

- The hash is **not cryptographically secure** for authentication (no HMAC/signing)
- The hash **detects accidental or malicious changes** to frontmatter after compilation
- The hash **does not protect** against modifications before compilation
- The hash is designed to **detect stale lock files** — it catches cases where the frontmatter has changed since the lock file was last compiled
- The hash **does not guarantee tamper protection**: anyone with write access to the repository can modify both the `.md` source and the `.lock.yml` file together, bypassing detection
- Always validate workflow sources through proper code review processes

## Versioning
Expand Down
Loading