Skip to content

chore(ci): harden issue-fields backfill and record verification - #1405

Open
ashleyshaw wants to merge 5 commits into
developfrom
chore/phase-2b-backfill-debug-pack
Open

chore(ci): harden issue-fields backfill and record verification#1405
ashleyshaw wants to merge 5 commits into
developfrom
chore/phase-2b-backfill-debug-pack

Conversation

@ashleyshaw

Copy link
Copy Markdown
Member

Chore Pull Request

Linked issues

Closes #1404

Summary

Hardens the Issue Fields backfill workflow to remove deprecated runtime warnings, improve project number parsing safety, and document remediation progress for Phase 2B.

Changes

Impact / Compatibility

  • Runtime/behaviour changes: workflow-only; no product/runtime surface changes.
  • Build/dev-experience impact: improved workflow diagnostics and stability.

Verification

  • CI passes
  • Local build and smoke tests
  • Docs updated if developer-facing

Risk & Rollback

  • Risk level: Low
  • Rollback plan: revert the branch commits.

Changelog

Added

Changed

  • Updated issue-fields-backfill.yml to hardened action/runtime and project parsing logic.

Fixed

  • Removed Node 20 deprecation and invalid project number coercion warnings from the backfill run path.

Removed

  • None.

Checklist (Global DoD / PR)

  • All AC met and demonstrated
  • Tests added/updated (unit/E2E as appropriate)
  • Accessibility checklist completed (where relevant)
  • Docs/readme/changelog updated (if user-facing)
  • Security checklist completed (where relevant)
  • Code/design reviews approved
  • CI green; linked issues closed; release notes prepared (if shipping)

@github-actions github-actions Bot added status:needs-review Awaiting code review type:chore Chore / small hygiene change labels Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved issue field backfill reliability with safer project-number validation and fallback handling.
    • Added repository-level issue type synchronisation when broader access is unavailable.
    • Resolved invalid project-number errors and reduced Node.js deprecation warnings.
    • Added clearer diagnostics when project details or permissions cannot be retrieved.
  • Documentation

    • Updated planning documentation with follow-up remediation tasks and validation steps.
    • Added changelog entries covering the backfill workflow improvements.

Walkthrough

The pull request upgrades workflow actions, adds validated Projects v2 number resolution, introduces repository-scoped issue-type fallback handling, updates the issue-type mutation input, and records remediation tasks and changelog entries.

Changes

Issue field backfill

Layer / File(s) Summary
Workflow runtime and project synchronisation
.github/workflows/issue-fields-backfill.yml
Uses updated GitHub Actions, resolves project numbers from validated inputs or URLs, and avoids project metadata queries when resolution fails.
Native issue type synchronisation
.github/workflows/issue-fields-backfill.yml
Fetches organisation issue types with fallback to repository-scoped data and updates issues through the issueTypeId mutation input.
Remediation tracking and release notes
projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md, CHANGELOG.md
Adds remediation checklist details, updates audit attribution, and records the workflow hardening and fixes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BackfillWorkflow
  participant ProjectResolver
  participant GitHubGraphQL
  participant IssueTypeSources
  BackfillWorkflow->>ProjectResolver: Resolve configured project number or URL
  ProjectResolver-->>BackfillWorkflow: Return valid number or invalid result
  BackfillWorkflow->>GitHubGraphQL: Query project metadata when valid
  BackfillWorkflow->>IssueTypeSources: Fetch organisation issue types
  IssueTypeSources-->>BackfillWorkflow: Return organisation map or empty result
  BackfillWorkflow->>IssueTypeSources: Fetch repository issue types when needed
  IssueTypeSources-->>BackfillWorkflow: Return fallback issue type map
  BackfillWorkflow->>GitHubGraphQL: Update issue with issueTypeId
Loading

Possibly related issues

Possibly related PRs

  • lightspeedwp/.github#1401: Updates the same backfill workflow’s native issue-type GraphQL fetching and mutation handling.

Suggested labels: lang:yaml

Suggested reviewers: lightspeedwp

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR does not address #1404's workflow-validation failures or the listed failing workflows, so it misses the linked issue's core remediation. Update the listed workflows for #1404, extract any embedded control flow into scripts, and verify npm run validate:workflows reaches zero errors.
Out of Scope Changes check ⚠️ Warning The workflow and documentation changes target issue-fields-backfill, which is outside #1404's scoped failing workflows. Remove or split out the backfill and documentation edits, or retarget the PR to the issue-fields-backfill remediation if that is the intended scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly matches the main CI hardening and verification changes.
Description check ✅ Passed It covers the linked issue, summary, changelog, risk, verification, and checklist, though the test section is less detailed than the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch chore/phase-2b-backfill-debug-pack
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/phase-2b-backfill-debug-pack

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the priority:normal Default priority label Jul 29, 2026
@github-actions github-actions Bot added area:ci Build and CI pipelines area:documentation Docs & guides lang:md Markdown content/docs type:bug Bug or defect meta:needs-changelog Requires a changelog entry before merge labels Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

⏱️ Aging and SLA annotation

  • Age: 0 day(s)
  • SLA state: Within SLA
  • Thresholds: warn at 7 days, breach at 14 days
  • Last updated: 2026-07-29T20:30:52.981Z

Maintained by project-meta-sync workflow.

@coderabbitai coderabbitai Bot added area:scripts Scripts & tooling lang:js JavaScript/TypeScript type:ci CI/CD pipeline work labels Jul 29, 2026
@github-actions github-actions Bot removed type:chore Chore / small hygiene change type:ci CI/CD pipeline work labels Jul 29, 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: 5

🤖 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/issue-fields-backfill.yml:
- Around line 217-220: Update the project-identifier resolution around
resolveProjectNumberFromUrl so that when both PROJECT_NUMBER and PROJECT_URL
produce valid numbers, conflicting values are rejected before backfill proceeds,
with an actionable error. Preserve the existing fallback behavior when only one
source is valid, and ensure any mismatch handling reports the conflicting
identifiers rather than silently preferring projectNumber.
- Around line 223-227: The invalid project-number branch in the workflow must
fail before any writes rather than only issuing core.warning; update the
validation around projNum to propagate an actual failure while preserving the
existing diagnostic context. In
projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md:542, keep the
item open until this workflow failure behavior is implemented, or revise the
documented claim to explicitly describe warning-and-skip behavior.
- Around line 175-178: Update the org issue-types fallback around core.warning
so the generated run summary also reports the missing org-level permission
guidance, not only the log warning. In
.github/workflows/issue-fields-backfill.yml lines 175-178, add this diagnostic
to the report-generation path; in
projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md line 544, keep
the checklist item open until that summary behavior exists, or explicitly
document that diagnostics are log-only.
- Around line 118-127: Update resolveProjectNumberFromUrl and the PROJECT_NUMBER
input handling to use one shared strict project-number parser: accept decimal
digits only, convert without partial parsing, and require a safe integer in the
inclusive range 1–2147483647; return the existing invalid/NaN result for
malformed, zero, negative, or out-of-range values.
- Around line 77-81: Update the actions/create-github-app-token@v3 configuration
to limit the token to the current repository by adding the repositories input,
and explicitly declare only the required permissions, including issues write,
contents read, and projects write where supported by the installation. Keep the
existing app-id, private-key, and owner inputs unchanged.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 44d46548-5ca4-4969-b0f9-7042cd56242a

📥 Commits

Reviewing files that changed from the base of the PR and between 8fcd64f and a92a603.

📒 Files selected for processing (2)
  • .github/workflows/issue-fields-backfill.yml
  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: Testing
  • GitHub Check: coderabbit-gate
  • GitHub Check: Analyze (python)
  • GitHub Check: Mergify Merge Protections
  • GitHub Check: Summary
⚠️ CI failures not shown inline (2)

GitHub Actions: Changelog • Management / 0_Validate changelog on PR.txt: chore(ci): harden issue-fields backfill and record verification

Conclusion: failure

View job details

##[group]Run actions/github-script@v7
 with:
   script: const cp = require("node:child_process");
const author = context.payload.pull_request?.user?.login || "";
const labels = (context.payload.pull_request?.labels || []).map((l) => l.name);
const has = (name) => labels.includes(name);
if (author === "dependabot[bot]" || author === "app/dependabot") {
  core.info("Skipping changelog requirement for Dependabot pull requests.");
  core.setOutput("run_validation", "false");
  return;
}
if (has("meta:needs-changelog") && has("meta:no-changelog")) {
  core.setFailed("PR cannot include both meta:needs-changelog and meta:no-changelog.");
  return;
}
const restrictedTypes = new Set([
  "type:feature",
  "type:bug",
  "type:performance",
  "type:security",
  "type:release",
  "type:hotfix",
]);
if (has("meta:no-changelog") && labels.some((label) => restrictedTypes.has(label))) {
  core.setFailed("meta:no-changelog is not allowed for high-impact release-related change types.");
  return;
}
const baseSha = context.payload.pull_request?.base?.sha;
const headSha = context.payload.pull_request?.head?.sha;
const changed = cp
  .execSync(`git diff --name-only ${baseSha} ${headSha}`, {
    encoding: "utf8",
    maxBuffer: 1024 * 1024 * 100,
  })
  .split("\n")
  .filter(Boolean);
if (changed.includes("CHANGELOG.md")) {
  core.info("CHANGELOG.md updated in PR diff.");
  core.setOutput("run_validation", "true");
  return;
}
if (has("meta:no-changelog")) {
  core.info("Skipping changelog requirement due to meta:no-changelog label.");
  core.setOutput("run_validation", "false");
  return;
}
core.setFailed("PR requires a CHANGELOG.md update or the meta:no-changelog label.");
   github-***REDACTED_SECRET_ASSIGNMENT***
   debug: false
   user-agent: actions/github-script
   result-encoding: json
   retries: 0
   retry-exempt-status-codes: 400,401,403,404,422
 ##[endgroup]
 ##[error]PR requires a CHANGELOG.md update or the meta:no-changelog label.

GitHub Actions: Changelog • Management / Validate changelog on PR: chore(ci): harden issue-fields backfill and record verification

Conclusion: failure

View job details

##[group]Run actions/github-script@v7
 with:
   script: const cp = require("node:child_process");
const author = context.payload.pull_request?.user?.login || "";
const labels = (context.payload.pull_request?.labels || []).map((l) => l.name);
const has = (name) => labels.includes(name);
if (author === "dependabot[bot]" || author === "app/dependabot") {
  core.info("Skipping changelog requirement for Dependabot pull requests.");
  core.setOutput("run_validation", "false");
  return;
}
if (has("meta:needs-changelog") && has("meta:no-changelog")) {
  core.setFailed("PR cannot include both meta:needs-changelog and meta:no-changelog.");
  return;
}
const restrictedTypes = new Set([
  "type:feature",
  "type:bug",
  "type:performance",
  "type:security",
  "type:release",
  "type:hotfix",
]);
if (has("meta:no-changelog") && labels.some((label) => restrictedTypes.has(label))) {
  core.setFailed("meta:no-changelog is not allowed for high-impact release-related change types.");
  return;
}
const baseSha = context.payload.pull_request?.base?.sha;
const headSha = context.payload.pull_request?.head?.sha;
const changed = cp
  .execSync(`git diff --name-only ${baseSha} ${headSha}`, {
    encoding: "utf8",
    maxBuffer: 1024 * 1024 * 100,
  })
  .split("\n")
  .filter(Boolean);
if (changed.includes("CHANGELOG.md")) {
  core.info("CHANGELOG.md updated in PR diff.");
  core.setOutput("run_validation", "true");
  return;
}
if (has("meta:no-changelog")) {
  core.info("Skipping changelog requirement due to meta:no-changelog label.");
  core.setOutput("run_validation", "false");
  return;
}
core.setFailed("PR requires a CHANGELOG.md update or the meta:no-changelog label.");
   github-***REDACTED_SECRET_ASSIGNMENT***
   debug: false
   user-agent: actions/github-script
   result-encoding: json
   retries: 0
   retry-exempt-status-codes: 400,401,403,404,422
 ##[endgroup]
 ##[error]PR requires a CHANGELOG.md update or the meta:no-changelog label.
🧰 Additional context used
📓 Path-based instructions (4)
**/.github/workflows/*.yml

⚙️ CodeRabbit configuration file

**/.github/workflows/*.yml: Review GitHub Actions workflows for this governance repo:

  • Security: check for least-privilege permissions (use permissions: at job level, default to read-only).
  • Secret handling: ensure secrets are passed via env vars, not interpolated directly into run: steps to prevent injection.
  • Action pinning: prefer SHA-pinned actions over mutable tags (e.g. actions/checkout@v4 is acceptable; SHA pins are better).
  • No pull_request_target with untrusted code execution unless explicitly justified.
  • Avoid storing sensitive outputs as unmasked step outputs.
  • Check for reusable workflow patterns and matrix strategies where appropriate.
  • Validate on: triggers: ensure branch/path filters are present to avoid unnecessary runs.
  • Confirm workflows are documented, DRY, and maintainable.
  • Ensure agent-triggered workflows use workflow_dispatch with defined inputs.

Files:

  • .github/workflows/issue-fields-backfill.yml
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

**/*: Do not use claude/ as a branch prefix. Branches must use {type}/{scope}-{short-title} with lowercase kebab-case and an approved type prefix.
Feature, fix, chore, documentation, and similar branches must target develop; only release/* and hotfix/* branches may merge to main.
After a successful squash merge, delete the remote and local branch.
Never reuse a branch name after it has been merged; create a unique replacement name.
Reusable assets must be placed in the appropriate top-level portable folder rather than under .github/.
Do not move existing agents, instructions, or schemas without a migration issue recording the source path, target path, and validation plan.
Do not commit node_modules/, build/, or other generated artefacts.
Do not add WordPress plugin- or theme-specific code to the organisation .github control-plane repository.
Do not place reports or task trackers in docs/ or the repository root; use the designated reports and project directories.
Do not enqueue editor-only WordPress assets on the front end, or front-end-only assets in the editor.

**/*: Never output secrets, treat production and customer data as sensitive, and follow the OWASP Top 10 for web security.
Before editing, validate the branch with npm run validate:branch-name -- --branch <name>; use {type}/{scope}-{short-title}, never use a claude/ prefix, and ensure feature/fix/chore branches target develop while only release/hotfix branches target main.
Prefer minimal, modular solutions; justify heavier tools based on return on investment and maintenance cost.
When requirements are uncertain, propose safe defaults and ask one focused clarifying question.
Use the canonical coding, linting, quality-assurance, documentation-format, automation and community-standards instruction indexes when applying project standards.

Files:

  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use UK English throughout documentation and Markdown content, including spellings such as optimise, organisation, colour, and behaviour.

Use UK English and optimise written content for clarity, scalability, maintainability and profitable outcomes.

Files:

  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
**/*.{md,mdx,yml,yaml,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use a references frontmatter field; use inline links or footer sections instead.

Files:

  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
🪛 LanguageTool
projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md

[uncategorized] ~541-~541: The official name of this software platform is spelled with a capital “H”.
Context: .... - [x] Patch project number parsing in .github/workflows/issue-fields-backfill.yml ru...

(GITHUB)

🪛 zizmor (1.28.0)
.github/workflows/issue-fields-backfill.yml

[error] 81-81: dangerous use of GitHub App tokens (github-app): token granted access to all repositories for this owner's app installation

(github-app)


[error] 77-77: dangerous use of GitHub App tokens (github-app): app token inherits blanket installation permissions

(github-app)

🔇 Additional comments (3)
.github/workflows/issue-fields-backfill.yml (1)

83-84: LGTM!

projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md (2)

28-28: LGTM!


537-538: 📐 Maintainability & Code Quality

Align the completed checklist with the reviewed action versions.

This checklist item is scoped to the Workflow Backfill Debug Pack, and the pack’s workflow uses actions/create-github-app-token@v2 and actions/github-script@v7. No change needed here unless the item is intended to cover other workflows that already pinned to @v3/@v9.

			> Likely an incorrect or invalid review comment.

Comment on lines +77 to +81
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.LS_APP_ID }}
private-key: ${{ secrets.LS_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
sed -n '1,280p' .github/workflows/issue-fields-backfill.yml

echo
echo "== related tokens/permissions =="
rg -n "create-github-app-token|permissions:|id-token|contents:|pull-requests:|issues:" .github/workflows/issue-fields-backfill.yml .github/workflows || true

echo
echo "== package/action versions nearby =="
rg -n "actions/create-github-app-token" .github/workflows || true

Repository: lightspeedwp/.github

Length of output: 21518


🌐 Web query:

actions/create-github-app-token v3 owner repositories inputs installation token default permissions documentation

💡 Result:

The actions/create-github-app-token version 3 action is used to generate an installation access token for a GitHub App within a workflow [1][2]. Below is the summary of the requested inputs and default permission behavior. Input Parameters: - owner: Optional. Specifies the owner (user or organization) of the GitHub App installation [1][3]. If left empty, it defaults to the current repository owner [1][4]. - repositories: Optional. A comma or newline-separated list of repository names to which the token should have access [1][3]. - If owner is provided and repositories is empty, the token is scoped to all repositories in that owner's installation [1][3]. - If both owner and repositories are empty, the token is scoped to only the current repository [1][3]. - permission-: The action supports granular permission control via inputs prefixed with permission- (e.g., permission-pull-requests) [1][4]. These are dynamically generated based on the GitHub OpenAPI specification [5]. Default Permission Behavior: By default, if no specific permissions are requested via the permission- inputs, the generated installation token inherits all permissions that were granted to the GitHub App installation [1][4][6]. Important Considerations: - It is recommended to explicitly list the specific permissions required for your use case to adhere to the principle of least privilege, consistent with GitHub's guidelines for controlling GITHUB_TOKEN permissions [1][4]. - You cannot grant the token permissions or access to repositories that the App installation itself does not already possess [5][6]. - The version 3 release introduced several changes, including the use of client-id (replacing the deprecated app-id) and support for enterprise-level GitHub Apps [7][8].

Citations:


🌐 Web query:

"actions/create-github-app-token@v3" "repositories:" "permission-" README

💡 Result:

In the actions/create-github-app-token@v3 action, the permission- prefix is used to explicitly define the permissions granted to the generated installation access token [1]. By default, the token inherits all permissions assigned to the GitHub App installation [1][2]. However, it is recommended to explicitly list only the permissions required for your specific use case to follow the principle of least privilege [1]. To configure these permissions, you prefix the desired permission key with permission- in your workflow configuration (e.g., permission-pull-requests for pull-requests) [1]. For example: - To grant read access to pull requests: permission-pull-requests: read - To grant write access to metadata: permission-metadata: write Important considerations: 1. Installation vs. App Permissions: The permissions you set must be granted to the GitHub App installation itself [1][2]. If you request a permission that the installation does not possess, the action will return an error [1]. 2. Administrative Approval: If you add new permissions to an app after it has been installed, an account administrator must approve these changes before they become effective on the installation [1][2]. 3. Repositories Input: The repositories input allows you to scope the token to specific repositories [1][2]. If this input is omitted, the token is scoped to the current repository by default [2]. If the owner input is provided but repositories is empty, the token is scoped to all repositories in that installation [1][2].

Citations:


Whittle the GitHub App token down a smidge.

The owner input without repositories expands the installation token to every repo in the installation, and absent permission-* inputs the token can inherit every app permission. Scope it to the current repo and declare only the permissions the backfill actually needs, such as permission-issues: write, permission-content: read, and permission-projects: write (where the installation has them).

🔐 Suggested tightening
           owner: ${{ github.repository_owner }}
+          repositories: ${{ github.event.repository.name }}
+          # Add only the required permission-* inputs after confirming app scopes.
         id-token: write
🧰 Tools
🪛 zizmor (1.28.0)

[error] 81-81: dangerous use of GitHub App tokens (github-app): token granted access to all repositories for this owner's app installation

(github-app)


[error] 77-77: dangerous use of GitHub App tokens (github-app): app token inherits blanket installation permissions

(github-app)

🤖 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/issue-fields-backfill.yml around lines 77 - 81, Update the
actions/create-github-app-token@v3 configuration to limit the token to the
current repository by adding the repositories input, and explicitly declare only
the required permissions, including issues write, contents read, and projects
write where supported by the installation. Keep the existing app-id,
private-key, and owner inputs unchanged.

Sources: Path instructions, MCP tools, Linters/SAST tools

Comment on lines +118 to +127
function resolveProjectNumberFromUrl(url) {
try {
const segments = new URL(url).pathname.split('/').filter(Boolean);
const projectsIdx = segments.indexOf('projects');
if (projectsIdx < 0 || projectsIdx === segments.length - 1) return Number.NaN;
return parseInt(segments[projectsIdx + 1], 10);
} catch {
return Number.NaN;
}
}

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file info =="
wc -l .github/workflows/issue-fields-backfill.yml 2>/dev/null || true

echo "== relevant sections =="
sed -n '100,135p' .github/workflows/issue-fields-backfill.yml 2>/dev/null || true
sed -n '205,235p' ..github/workflows/issue-fields-backfill.yml 2>/dev/null || true

echo "== parseInt usage in file =="
rg -n "parseInt|resolveProjectNumberFromUrl|projectNumber|MAX|NaN|Int!" .github/workflows/issue-fields-backfill.yml 2>/dev/null || true

echo "== deterministic parseInt/coercion probe =="
node - <<'JS'
const inputs = ['123', '123junk', '0123', '1.5', '1.23e2', '123abcXYZ', '9007199254740992', '2147483648', '2147483647', '2147483646'];
for (const s of inputs) {
  console.log(`${s.padEnd(23)} parseInt=`, parseInt(s, 10),
    `Number=`, Number(s),
    `digitsOnly=`, /^\d+$/.test(s),
    `safePositiveInt=`, Number.isSafeInteger(Number(s)) && Number(s) > 0);
}
JS

Repository: lightspeedwp/.github

Length of output: 4032


Enforce a strict project-number parser.

parseInt can accept leading digits, so values like 123junk are parsed as 123; the later numeric check also allows values that exceed GraphQL’s signed 32-bit range (2147483647). For both URL-derived and PROJECT_NUMBER inputs, use one strict handler: decimal digits only, safe integer, and 1 ≤ n ≤ 2147483647.

Applies to lines 119-124 and 246-247.

🤖 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/issue-fields-backfill.yml around lines 118 - 127, Update
resolveProjectNumberFromUrl and the PROJECT_NUMBER input handling to use one
shared strict project-number parser: accept decimal digits only, convert without
partial parsing, and require a safe integer in the inclusive range 1–2147483647;
return the existing invalid/NaN result for malformed, zero, negative, or
out-of-range values.

Source: MCP tools

Comment thread .github/workflows/issue-fields-backfill.yml
Comment on lines +217 to +220
const projNumFromUrl = resolveProjectNumberFromUrl(projectUrl);
const projNum = Number.isInteger(projectNumber) && projectNumber > 0
? projectNumber
: projNumFromUrl;

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject conflicting project identifiers.

When PROJECT_NUMBER and PROJECT_URL resolve to different valid projects, this silently chooses PROJECT_NUMBER while the log still displays projectUrl. Reject the mismatch or make one source explicitly authoritative and report that choice; otherwise the backfill can target the wrong project.

🤖 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/issue-fields-backfill.yml around lines 217 - 220, Update
the project-identifier resolution around resolveProjectNumberFromUrl so that
when both PROJECT_NUMBER and PROJECT_URL produce valid numbers, conflicting
values are rejected before backfill proceeds, with an actionable error. Preserve
the existing fallback behavior when only one source is valid, and ensure any
mismatch handling reports the conflicting identifiers rather than silently
preferring projectNumber.

Comment on lines +223 to +227
if (!Number.isInteger(projNum) || projNum <= 0) {
core.warning(
`Could not parse a valid project number. ` +
`PROJECT_NUMBER="${process.env.PROJECT_NUMBER || ''}" PROJECT_URL="${projectUrl}"`
);

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

The documented fail-fast guardrail is not implemented.

  • .github/workflows/issue-fields-backfill.yml#L223-L227: validate before writes and propagate an actual failure when the project number is invalid.
  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md#L542-L542: keep the item open until the workflow fails accordingly, or change the claim to warning-and-skip behaviour.
📍 Affects 2 files
  • .github/workflows/issue-fields-backfill.yml#L223-L227 (this comment)
  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md#L542-L542
🤖 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/issue-fields-backfill.yml around lines 223 - 227, The
invalid project-number branch in the workflow must fail before any writes rather
than only issuing core.warning; update the validation around projNum to
propagate an actual failure while preserving the existing diagnostic context. In
projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md:542, keep the
item open until this workflow failure behavior is implemented, or revise the
documented claim to explicitly describe warning-and-skip behavior.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Reviewer Summary for PR #1405

CI Status:success
Files changed: 2
Risk Distribution: 1 critical, 0 high, 0 medium, 1 low

Recommendations

  • ⚠️ 1 critical-risk file(s) modified (workflows, secrets)
  • ⚠️ Security-sensitive files modified (review carefully)

@github-actions github-actions Bot added the type:chore Chore / small hygiene change label Jul 29, 2026
@ashleyshaw
ashleyshaw enabled auto-merge (squash) July 29, 2026 21:13
@ashleyshaw

Copy link
Copy Markdown
Member Author

Recovery update: the accidental direct commit to develop (0f47b02) has been reverted on develop by commit 89f9564, and the fix remains on this PR branch at c170804. This PR is now the canonical place for the backfill mutation fix.

- Added CHANGELOG.md entries (Fixed + Changed) for PR #1405 to satisfy
  Changelog Management check
- Fixed footer in PHASE-2B-SKILLS-PLANNING.md to audit-footer format to
  clear footer validation failure in CI Unified Checks
- Corrected UK English spelling (behaviour) in changelog entry per
  CodeRabbit review

Relates to #1404
@coderabbitai coderabbitai Bot added lang:yaml YAML config and removed area:scripts Scripts & tooling lang:js JavaScript/TypeScript labels Jul 29, 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: 1

🤖 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/issue-fields-backfill.yml:
- Around line 78-80: Update the workflow validation setup for
.github/workflows/issue-fields-backfill.yml by refreshing actionlint’s action
metadata or pinning actionlint to a version that recognizes the client-id input
for actions/create-github-app-token@v3. Keep client-id configured and do not
replace it with the deprecated app-id fallback; ensure required workflow
validation completes with zero errors.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a876b1a-fc57-4729-a7c3-b258d64d3543

📥 Commits

Reviewing files that changed from the base of the PR and between a92a603 and a440b8b.

📒 Files selected for processing (3)
  • .github/workflows/issue-fields-backfill.yml
  • CHANGELOG.md
  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • projects/active/phase-2b-skills-audit/PHASE-2B-SKILLS-PLANNING.md
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (python)
  • GitHub Check: Mergify Merge Protections
  • GitHub Check: Summary
🧰 Additional context used
📓 Path-based instructions (5)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

**/*: Do not use claude/ as a branch prefix. Branches must use {type}/{scope}-{short-title} with lowercase kebab-case and an approved type prefix.
Feature, fix, chore, documentation, and similar branches must target develop; only release/* and hotfix/* branches may merge to main.
After a successful squash merge, delete the remote and local branch.
Never reuse a branch name after it has been merged; create a unique replacement name.
Reusable assets must be placed in the appropriate top-level portable folder rather than under .github/.
Do not move existing agents, instructions, or schemas without a migration issue recording the source path, target path, and validation plan.
Do not commit node_modules/, build/, or other generated artefacts.
Do not add WordPress plugin- or theme-specific code to the organisation .github control-plane repository.
Do not place reports or task trackers in docs/ or the repository root; use the designated reports and project directories.
Do not enqueue editor-only WordPress assets on the front end, or front-end-only assets in the editor.

**/*: Never output secrets, treat production and customer data as sensitive, and follow the OWASP Top 10 for web security.
Before editing, validate the branch with npm run validate:branch-name -- --branch <name>; use {type}/{scope}-{short-title}, never use a claude/ prefix, and ensure feature/fix/chore branches target develop while only release/hotfix branches target main.
Prefer minimal, modular solutions; justify heavier tools based on return on investment and maintenance cost.
When requirements are uncertain, propose safe defaults and ask one focused clarifying question.
Use the canonical coding, linting, quality-assurance, documentation-format, automation and community-standards instruction indexes when applying project standards.

Files:

  • CHANGELOG.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use UK English throughout documentation and Markdown content, including spellings such as optimise, organisation, colour, and behaviour.

Use UK English and optimise written content for clarity, scalability, maintainability and profitable outcomes.

Files:

  • CHANGELOG.md
**/*.{md,mdx,yml,yaml,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use a references frontmatter field; use inline links or footer sections instead.

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: Review CHANGELOG.md:

  • Confirm entries follow Keep a Changelog 1.1.0 format.
  • Each entry under [Unreleased] must include a PR link and issue link.
  • Verify entries use the correct section headings (Added, Changed, Fixed, Deprecated, Removed, Security, Documentation, Performance).
  • Check UK English spelling throughout.

Files:

  • CHANGELOG.md
**/.github/workflows/*.yml

⚙️ CodeRabbit configuration file

**/.github/workflows/*.yml: Review GitHub Actions workflows for this governance repo:

  • Security: check for least-privilege permissions (use permissions: at job level, default to read-only).
  • Secret handling: ensure secrets are passed via env vars, not interpolated directly into run: steps to prevent injection.
  • Action pinning: prefer SHA-pinned actions over mutable tags (e.g. actions/checkout@v4 is acceptable; SHA pins are better).
  • No pull_request_target with untrusted code execution unless explicitly justified.
  • Avoid storing sensitive outputs as unmasked step outputs.
  • Check for reusable workflow patterns and matrix strategies where appropriate.
  • Validate on: triggers: ensure branch/path filters are present to avoid unnecessary runs.
  • Confirm workflows are documented, DRY, and maintainable.
  • Ensure agent-triggered workflows use workflow_dispatch with defined inputs.

Files:

  • .github/workflows/issue-fields-backfill.yml
🪛 actionlint (1.7.12)
.github/workflows/issue-fields-backfill.yml

[error] 80-80: input "client-id" is not defined in action "actions/create-github-app-token@v3". available inputs are "app-id", "github-api-url", "owner", "permission-actions", "permission-administration", "permission-checks", "permission-codespaces", "permission-contents", "permission-custom-properties-for-organizations", "permission-dependabot-secrets", "permission-deployments", "permission-email-addresses", "permission-enterprise-custom-properties-for-organizations", "permission-environments", "permission-followers", "permission-git-ssh-keys", "permission-gpg-keys", "permission-interaction-limits", "permission-issues", "permission-members", "permission-metadata", "permission-organization-administration", "permission-organization-announcement-banners", "permission-organization-copilot-seat-management", "permission-organization-custom-org-roles", "permission-organization-custom-properties", "permission-organization-custom-roles", "permission-organization-events", "permission-organization-hooks", "permission-organization-packages", "permission-organization-personal-access-token-requests", "permission-organization-personal-access-tokens", "permission-organization-plan", "permission-organization-projects", "permission-organization-secrets", "permission-organization-self-hosted-runners", "permission-organization-user-blocking", "permission-packages", "permission-pages", "permission-profile", "permission-pull-requests", "permission-repository-custom-properties", "permission-repository-hooks", "permission-repository-projects", "permission-secret-scanning-alerts", "permission-secrets", "permission-security-events", "permission-single-file", "permission-starring", "permission-statuses", "permission-team-discussions", "permission-vulnerability-alerts", "permission-workflows", "private-key", "repositories", "skip-token-revoke"

(action)

🔇 Additional comments (6)
.github/workflows/issue-fields-backfill.yml (5)

80-83: Keep the app token on a short leash.

With owner set and no repositories or permission-* inputs, the token spans every repository in the installation and inherits its permissions. Scope it to the required repository set and explicitly request only the permissions this backfill needs. (raw.githubusercontent.com)

Source: Path instructions


119-124: Parse project numbers strictly.

parseInt accepts trailing non-digits, so 123junk resolves to project 123 and can write to the wrong board. Use one decimal-only, bounded parser for both environment and URL-derived values. (tc39.es)

Also applies to: 245-248


245-248: Reject conflicting project identifiers.

When both identifiers are valid but disagree, this silently selects PROJECT_NUMBER while logging the URL. Fail before any query or write when they resolve to different project numbers.


9-10: LGTM!


159-229: LGTM!

CHANGELOG.md (1)

93-94: LGTM!

Also applies to: 115-116

Comment on lines +78 to +80
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.LS_APP_ID }}
client-id: ${{ vars.LS_APP_CLIENT_ID != '' && vars.LS_APP_CLIENT_ID || vars.LS_APP_ID }}

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow relevant lines =="
if [ -f .github/workflows/issue-fields-backfill.yml ]; then
  nl -ba .github/workflows/issue-fields-backfill.yml | sed -n '1,130p'
else
  echo "workflow file not found"
fi

echo
echo "== actionlint references =="
rg -n "actionlint|create-github-app-token|app-id|client-id" .github/workflows . 2>/dev/null | sed -n '1,200p'

echo
echo "== read-only metadata/version snippets if available =="
python3 - <<'PY'
from pathlib import Path
import re
for p in Path('.github').rglob('*.yml'):
    txt=p.read_text(errors='ignore')
    if 'actionlint' in txt or 'create-github-app-token' in txt:
        print(f"\n--- {p} ---")
        for i,line in enumerate(txt.splitlines(),1):
            if 'actionlint' in line or 'create-github-app-token' in line or 'app-id' in line or 'client-id' in line:
                print(f"{i}: {line}")
PY

Repository: lightspeedwp/.github

Length of output: 228


🌐 Web query:

actions/create-github-app-token v3 README client-id app-input README

💡 Result:

In the actions/create-github-app-token v3 documentation, the client-id input is the recommended way to provide the GitHub App identifier for authentication [1][2]. While the action still supports app-id for backwards compatibility, it has been officially deprecated [1][2]. The action's runtime logic is configured to prefer client-id; if both inputs are provided, client-id takes precedence [2][3]. If neither input is provided, the action will return an error [2][3]. To use the action in a workflow, you should store your GitHub App's Client ID in a repository variable (e.g., APP_CLIENT_ID) and your private key in a repository secret (e.g., APP_PRIVATE_KEY), and then reference them in your workflow step [4][1][5]: - uses: actions/create-github-app-token@v3 id: app-token with: client-id: ${{ vars.APP_CLIENT_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} The documentation does not refer to an input named app-input; rather, it uses client-id (the recommended input) or the legacy app-id to specify the application identity [1][2][5].

Citations:


🌐 Web query:

ReviewDog actionlint command config actionlint GitHub Actions input unknown

💡 Result:

The error "input unknown" or "not defined" when using the reviewdog/action-actionlint GitHub Action typically occurs because the input parameter you are attempting to use is not supported by the specific version of the action you have configured [1][2]. To resolve this issue, check the following steps: 1. Verify Valid Inputs: Ensure the input name you are using is defined in the action's configuration. The currently supported inputs for reviewdog/action-actionlint are [3][4]: - github_token - tool_name - level - reporter - filter_mode - fail_level - fail_on_error (deprecated) - reviewdog_flags - actionlint_flags 2. Check Your Version: If you are trying to use a newer feature like 'fail_level', ensure you are using a recent version of the action that supports it [2]. If you are pinned to an older version (e.g., using a specific tag or hash), the newer inputs will not be recognized, resulting in the "not defined" error [2]. Update your workflow's uses statement to point to a later version or the latest release [5][4]. 3. Common Pitfall: Users often encounter this error when trying to add unsupported parameters, such as 'workdir', which is not a valid input for this action [1]. Since actionlint automatically targets the repository's workflow directory, specific working directory overrides are generally not supported as action inputs [1]. 4. Distinguish Action vs. Tool: Remember that actionlint is the underlying tool, and reviewdog/action-actionlint is the wrapper [5][6]. Errors about "unknown inputs" usually refer to the wrapper's with: configuration, not the flags passed to the actionlint tool itself [2]. If you need to pass additional configuration to the actionlint tool, use the actionlint_flags input instead [5][3][4].

Citations:


🌐 Web query:

github actions create-github-app-token v3 client-id

💡 Result:

In version 3 of the actions/create-github-app-token action, the client-id input was introduced as the recommended parameter for identifying the GitHub App [1][2]. Key details regarding the use of client-id include: - Recommendation: It is now the preferred way to specify the GitHub App, replacing the legacy app-id input [3][2]. - Backwards Compatibility: The action still accepts app-id for backwards compatibility, though it is marked as deprecated [2][4]. - Precedence: If both client-id and app-id are provided, the action will prioritize client-id [2]. - Configuration: You should store your App's Client ID in your repository or organization variables (e.g., as APP_CLIENT_ID) and pass it to the action via the workflow file [3][5]: - uses: actions/create-github-app-token@v3 with: client-id: ${{ vars.APP_CLIENT_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} Ensure that the corresponding private key for the GitHub App is stored as a repository secret and passed to the private-key input [3][6]. If neither client-id nor app-id is provided, the action will return an error [2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo errexit

echo "== candidate files =="
git ls-files '.github/workflows/*.yml' '.github/workflows/*.yaml' 2>/dev/null | sed -n '1,120p'

echo
echo "== target workflow with line numbers =="
sed -n '1,140p' .github/workflows/issue-fields-backfill.yml | awk '{printf "%6d\t%s\n", NR, $0}'

echo
echo "== actionlint refs across tracked workflow files =="
git ls-files '.github/workflows/*.yml' '.github/workflows/*.yaml' 2>/dev/null \
  | xargs grep -nE "actionlint|create-github-app-token|app-id|client-id" 2>/dev/null || true

Repository: lightspeedwp/.github

Length of output: 8449


🌐 Web query:

rhysd actionlint releases unknown inputs create-github-app-token client-id

💡 Result:

The issue where actionlint reports unknown inputs or missing required inputs when using actions/create-github-app-token@v3 with the client-id input is a known false-positive caused by stale metadata in actionlint's internal registry [1][2]. When actions/create-github-app-token updated its v3 action.yml to introduce client-id as the canonical input (deprecating the legacy app-id), actionlint's bundled definition of popular actions was not immediately synchronized [1][2]. This caused actionlint to: - Incorrectly report that the required app-id input was missing [1][3][2]. - Incorrectly report that the valid client-id input was undefined [1][3][2]. This has been addressed in recent updates to actionlint [3][2]. To resolve this, ensure you are using an up-to-date version of actionlint [4][5]. If you are on an older version and cannot upgrade, you can suppress these specific false-positives by adding the following to your.github/actionlint.yaml configuration file [1]: paths:.github/workflows//*.{yml,yaml}: ignore: - 'missing input "app-id" which is required by action "actions/create-github-app-token@' - 'input "client-id" is not defined in action "actions/create-github-app-token@'

Citations:


Refresh actionlint’s action metadata or pin the validator.

actions/create-github-app-token@v3 legitimately supports client-id, but older actionlint metadata can still flag it as unknown and block the required zero-error workflow validation. Bump the validator or patch its action registry; don’t fall back to the deprecated app-id.

🧰 Tools
🪛 actionlint (1.7.12)

[error] 78-78: missing input "app-id" which is required by action "actions/create-github-app-token@v3". all required inputs are "app-id", "private-key"

(action)


[error] 80-80: input "client-id" is not defined in action "actions/create-github-app-token@v3". available inputs are "app-id", "github-api-url", "owner", "permission-actions", "permission-administration", "permission-checks", "permission-codespaces", "permission-contents", "permission-custom-properties-for-organizations", "permission-dependabot-secrets", "permission-deployments", "permission-email-addresses", "permission-enterprise-custom-properties-for-organizations", "permission-environments", "permission-followers", "permission-git-ssh-keys", "permission-gpg-keys", "permission-interaction-limits", "permission-issues", "permission-members", "permission-metadata", "permission-organization-administration", "permission-organization-announcement-banners", "permission-organization-copilot-seat-management", "permission-organization-custom-org-roles", "permission-organization-custom-properties", "permission-organization-custom-roles", "permission-organization-events", "permission-organization-hooks", "permission-organization-packages", "permission-organization-personal-access-token-requests", "permission-organization-personal-access-tokens", "permission-organization-plan", "permission-organization-projects", "permission-organization-secrets", "permission-organization-self-hosted-runners", "permission-organization-user-blocking", "permission-packages", "permission-pages", "permission-profile", "permission-pull-requests", "permission-repository-custom-properties", "permission-repository-hooks", "permission-repository-projects", "permission-secret-scanning-alerts", "permission-secrets", "permission-security-events", "permission-single-file", "permission-starring", "permission-statuses", "permission-team-discussions", "permission-vulnerability-alerts", "permission-workflows", "private-key", "repositories", "skip-token-revoke"

(action)

🪛 zizmor (1.28.0)

[error] 78-78: dangerous use of GitHub App tokens (github-app): app token inherits blanket installation permissions

(github-app)

🤖 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/issue-fields-backfill.yml around lines 78 - 80, Update the
workflow validation setup for .github/workflows/issue-fields-backfill.yml by
refreshing actionlint’s action metadata or pinning actionlint to a version that
recognizes the client-id input for actions/create-github-app-token@v3. Keep
client-id configured and do not replace it with the deprecated app-id fallback;
ensure required workflow validation completes with zero errors.

Source: Linters/SAST tools

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

Labels

area:ci Build and CI pipelines area:documentation Docs & guides lang:md Markdown content/docs lang:yaml YAML config meta:needs-changelog Requires a changelog entry before merge priority:normal Default priority status:needs-review Awaiting code review type:bug Bug or defect type:chore Chore / small hygiene change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ci): replace multiline run-block control flow to clear validate:workflows errors

1 participant