@htekdev/actions-debugger 1.0.22 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/errors/known-unsolved/reusable-secrets-inherit-not-deep-forwarded.yml +113 -0
- package/errors/runner-environment/org-runner-group-dispatch-null.yml +102 -0
- package/errors/triggers/workflow-run-checkout-uses-default-branch.yml +114 -0
- package/errors/yaml-syntax/reusable-workflow-nesting-depth-exceeded.yml +113 -0
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
id: known-unsolved-021
|
|
2
|
+
title: "secrets: inherit Does Not Cascade to Second-Level Nested Reusable Workflows"
|
|
3
|
+
category: known-unsolved
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- reusable-workflow
|
|
7
|
+
- secrets
|
|
8
|
+
- secrets-inherit
|
|
9
|
+
- nesting
|
|
10
|
+
- silent-failure
|
|
11
|
+
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "secret .+ is required, but not provided"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "secrets\\.\\w+ is not a valid secret key"
|
|
16
|
+
flags: "i"
|
|
17
|
+
|
|
18
|
+
error_messages:
|
|
19
|
+
- "Secret GIT_PAT is required, but not provided"
|
|
20
|
+
- "Required secret 'MY_SECRET' was not provided by the caller"
|
|
21
|
+
|
|
22
|
+
root_cause: |
|
|
23
|
+
`secrets: inherit` in a caller workflow passes ALL repository and organization
|
|
24
|
+
secrets to the directly-called (first-level) reusable workflow. However, if that
|
|
25
|
+
reusable workflow then calls ANOTHER reusable workflow (second level), those
|
|
26
|
+
inherited secrets are NOT automatically forwarded to the second level.
|
|
27
|
+
|
|
28
|
+
Each `workflow_call` boundary is a discrete secrets scope. `secrets: inherit`
|
|
29
|
+
only covers one hop. If you have:
|
|
30
|
+
|
|
31
|
+
root.yml → (secrets: inherit) → level1.yml → level2.yml
|
|
32
|
+
|
|
33
|
+
then `level2.yml` receives an empty secrets context unless `level1.yml`
|
|
34
|
+
explicitly passes them via its own `secrets:` block.
|
|
35
|
+
|
|
36
|
+
This is a platform design decision, not a bug. GitHub has confirmed that
|
|
37
|
+
`secrets: inherit` does not cascade through multiple `workflow_call` layers.
|
|
38
|
+
There is no current mechanism for automatic multi-level secret propagation.
|
|
39
|
+
|
|
40
|
+
Community reports: actions/runner#2709 (open, labeled bug, 8 👍, 2023–2025),
|
|
41
|
+
community/discussions/23107.
|
|
42
|
+
|
|
43
|
+
fix: |
|
|
44
|
+
Explicitly declare and pass secrets at EVERY reusable workflow boundary.
|
|
45
|
+
|
|
46
|
+
For level1.yml to forward secrets to level2.yml, level1.yml must:
|
|
47
|
+
1. Declare secrets in its on.workflow_call.secrets block.
|
|
48
|
+
2. Pass those secrets explicitly in the jobs.*.secrets block when calling level2.yml.
|
|
49
|
+
|
|
50
|
+
Alternatively, use `secrets: inherit` at EACH level — but the calling workflow
|
|
51
|
+
(level1.yml) itself must also explicitly declare the secrets it expects so
|
|
52
|
+
they are available in its scope to pass down.
|
|
53
|
+
|
|
54
|
+
fix_code:
|
|
55
|
+
- language: yaml
|
|
56
|
+
label: "root.yml — caller uses secrets: inherit for first hop"
|
|
57
|
+
code: |
|
|
58
|
+
jobs:
|
|
59
|
+
call-level1:
|
|
60
|
+
uses: ./.github/workflows/level1.yml
|
|
61
|
+
secrets: inherit # passes ALL secrets to level1.yml only
|
|
62
|
+
|
|
63
|
+
- language: yaml
|
|
64
|
+
label: "level1.yml — must declare AND re-forward secrets to level2.yml"
|
|
65
|
+
code: |
|
|
66
|
+
on:
|
|
67
|
+
workflow_call:
|
|
68
|
+
secrets:
|
|
69
|
+
MY_SECRET:
|
|
70
|
+
required: true
|
|
71
|
+
DEPLOY_TOKEN:
|
|
72
|
+
required: false
|
|
73
|
+
|
|
74
|
+
jobs:
|
|
75
|
+
call-level2:
|
|
76
|
+
uses: ./.github/workflows/level2.yml
|
|
77
|
+
secrets:
|
|
78
|
+
MY_SECRET: ${{ secrets.MY_SECRET }} # explicit re-forward
|
|
79
|
+
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }} # explicit re-forward
|
|
80
|
+
|
|
81
|
+
- language: yaml
|
|
82
|
+
label: "level2.yml — must declare secrets it expects"
|
|
83
|
+
code: |
|
|
84
|
+
on:
|
|
85
|
+
workflow_call:
|
|
86
|
+
secrets:
|
|
87
|
+
MY_SECRET:
|
|
88
|
+
required: true
|
|
89
|
+
DEPLOY_TOKEN:
|
|
90
|
+
required: false
|
|
91
|
+
|
|
92
|
+
jobs:
|
|
93
|
+
use-secrets:
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- name: Use secret
|
|
97
|
+
run: echo "token length = ${#MY_SECRET}"
|
|
98
|
+
env:
|
|
99
|
+
MY_SECRET: ${{ secrets.MY_SECRET }}
|
|
100
|
+
|
|
101
|
+
prevention:
|
|
102
|
+
- "Audit every workflow_call boundary in nested reusable workflows — each hop must explicitly forward secrets."
|
|
103
|
+
- "Document required secrets at every level in workflow comments to avoid silent empty-string failures."
|
|
104
|
+
- "Use composite actions instead of nested reusable workflows when secrets do not need to cross job boundaries — composite actions share the parent job's secrets context automatically."
|
|
105
|
+
- "Test nested workflows by echoing a non-sensitive derived value (e.g., secret length) at each level to confirm propagation."
|
|
106
|
+
|
|
107
|
+
docs:
|
|
108
|
+
- url: "https://docs.github.com/en/actions/using-workflows/reusing-workflows#passing-secrets-to-nested-workflows"
|
|
109
|
+
label: "GitHub Docs — Passing secrets to nested workflows"
|
|
110
|
+
- url: "https://github.com/actions/runner/issues/2709"
|
|
111
|
+
label: "actions/runner#2709 — Passing secrets to reusable workflow does not work (open, 2023)"
|
|
112
|
+
- url: "https://github.com/orgs/community/discussions/23107"
|
|
113
|
+
label: "community/discussions#23107 — Inheriting secrets in reusable workflows"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
id: runner-environment-059
|
|
2
|
+
title: "Org-Level Self-Hosted Runner in Group Never Dispatched — Job Queued Indefinitely"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- self-hosted-runner
|
|
7
|
+
- runner-group
|
|
8
|
+
- org-runner
|
|
9
|
+
- queued
|
|
10
|
+
- dispatch
|
|
11
|
+
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "no runner.*matching.*label.*self-hosted"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "runner_group_id.*null"
|
|
16
|
+
flags: "i"
|
|
17
|
+
|
|
18
|
+
error_messages:
|
|
19
|
+
- "Can't find any online and idle self-hosted runner in the current repository, account/organization that matches the required labels: 'self-hosted, <group-name>'"
|
|
20
|
+
- "Waiting for a runner to pick up this job..."
|
|
21
|
+
|
|
22
|
+
root_cause: |
|
|
23
|
+
When a self-hosted runner is registered at the ORGANIZATION level and placed into
|
|
24
|
+
a runner group that has explicit repository access, the GitHub Actions dispatcher
|
|
25
|
+
sometimes fails to resolve the runner's group membership within the target
|
|
26
|
+
repository's scope. The job's metadata shows runner_group_id: null throughout the
|
|
27
|
+
entire wait period, meaning the internal broker never matched the org-level runner
|
|
28
|
+
to the queued job.
|
|
29
|
+
|
|
30
|
+
This affects runners using the V2 broker protocol
|
|
31
|
+
(broker.actions.githubusercontent.com) on GitHub Team and Enterprise plans.
|
|
32
|
+
The runner appears "Online" in the org settings, the runner group lists the target
|
|
33
|
+
repository as allowed, and the runs-on labels match — yet the job never starts.
|
|
34
|
+
|
|
35
|
+
Root technical cause: the dispatcher resolves runner group membership differently
|
|
36
|
+
for org-scoped runners vs. repo-scoped runners. When the runner is registered at
|
|
37
|
+
org scope, the broker does not propagate its group_id to the queued job record,
|
|
38
|
+
so no assignment occurs.
|
|
39
|
+
|
|
40
|
+
fix: |
|
|
41
|
+
Short-term workaround (immediate):
|
|
42
|
+
Re-register the runner at the REPOSITORY level instead of the organization level.
|
|
43
|
+
This bypasses the group dispatch path and the job is assigned immediately.
|
|
44
|
+
|
|
45
|
+
Long-term fix:
|
|
46
|
+
1. Monitor GitHub Actions runner releases for a fix to org-level group dispatch.
|
|
47
|
+
2. Use GitHub-hosted larger runners or runner scale sets (Actions Runner Controller)
|
|
48
|
+
for org-level sharing — these use a different dispatch mechanism that is not
|
|
49
|
+
affected by this bug.
|
|
50
|
+
3. If org-level management is required, use runner groups with repo-scoped runner
|
|
51
|
+
registration and rely on group access policies to control visibility.
|
|
52
|
+
|
|
53
|
+
fix_code:
|
|
54
|
+
- language: yaml
|
|
55
|
+
label: "Re-register runner at repository level (workaround)"
|
|
56
|
+
code: |
|
|
57
|
+
# 1. Remove the runner from the org-level runner list in GitHub UI:
|
|
58
|
+
# Settings → Actions → Runners → (select runner) → Remove runner
|
|
59
|
+
#
|
|
60
|
+
# 2. Re-register the runner at the REPO level:
|
|
61
|
+
# <repo> → Settings → Actions → Runners → New self-hosted runner
|
|
62
|
+
# Follow setup commands shown in the UI.
|
|
63
|
+
#
|
|
64
|
+
# 3. Your workflow runs-on stays the same:
|
|
65
|
+
jobs:
|
|
66
|
+
build:
|
|
67
|
+
runs-on: [self-hosted, my-runner-label]
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
|
|
71
|
+
- language: yaml
|
|
72
|
+
label: "Use Actions Runner Controller (ARC) for org-level runners"
|
|
73
|
+
code: |
|
|
74
|
+
# ARC scale sets are not affected by the org-runner group dispatch bug.
|
|
75
|
+
# Install the controller chart and create a runner scale set:
|
|
76
|
+
#
|
|
77
|
+
# helm install arc-runner-set \
|
|
78
|
+
# --namespace arc-runners \
|
|
79
|
+
# oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set \
|
|
80
|
+
# --set githubConfigUrl=https://github.com/<org> \
|
|
81
|
+
# --set githubConfigSecret.github_token=<token>
|
|
82
|
+
#
|
|
83
|
+
# Then reference in your workflow:
|
|
84
|
+
jobs:
|
|
85
|
+
build:
|
|
86
|
+
runs-on: arc-runner-set
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@v4
|
|
89
|
+
|
|
90
|
+
prevention:
|
|
91
|
+
- "Register self-hosted runners at repository level when possible to avoid org-level dispatch issues."
|
|
92
|
+
- "After registering a runner, trigger a test workflow immediately to confirm dispatch before relying on it in production."
|
|
93
|
+
- "Use Actions Runner Controller (ARC) scale sets for org-wide shared runners — ARC bypasses the runner group dispatch path."
|
|
94
|
+
- "Check runner_group_id via the API (`GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs`) when a job is stuck — null means dispatch failed at the broker level."
|
|
95
|
+
|
|
96
|
+
docs:
|
|
97
|
+
- url: "https://github.com/actions/runner/issues/4429"
|
|
98
|
+
label: "actions/runner#4429 — Org-level runner never dispatched despite correct group access (May 2026)"
|
|
99
|
+
- url: "https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners"
|
|
100
|
+
label: "GitHub Docs — Runner registration scopes"
|
|
101
|
+
- url: "https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/using-self-hosted-runners-in-a-workflow"
|
|
102
|
+
label: "GitHub Docs — Using self-hosted runners in a workflow"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
id: triggers-019
|
|
2
|
+
title: "workflow_run-Triggered Job Checks Out Default Branch, Not the Triggering PR's Branch"
|
|
3
|
+
category: triggers
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- workflow_run
|
|
7
|
+
- checkout
|
|
8
|
+
- default-branch
|
|
9
|
+
- silent-failure
|
|
10
|
+
- pull-request
|
|
11
|
+
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "workflow_run.*head_branch"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "github\\.event\\.workflow_run\\.head_branch"
|
|
16
|
+
flags: "i"
|
|
17
|
+
|
|
18
|
+
error_messages:
|
|
19
|
+
- "# No error message — the job silently runs against the wrong branch (e.g., main instead of the PR's feature branch)"
|
|
20
|
+
- "HEAD is now at <main-branch-commit> — expected feature branch content not present"
|
|
21
|
+
|
|
22
|
+
root_cause: |
|
|
23
|
+
When a workflow is triggered via `workflow_run`, the triggered workflow ALWAYS
|
|
24
|
+
runs in the context of the repository's DEFAULT branch, not the branch that
|
|
25
|
+
caused the original workflow to run.
|
|
26
|
+
|
|
27
|
+
This means that `actions/checkout` without an explicit `ref:` will check out
|
|
28
|
+
the default branch (e.g., `main`), even when the triggering workflow ran on a
|
|
29
|
+
feature branch or PR. The job may silently pass because it's testing old code
|
|
30
|
+
on `main` rather than the developer's new changes.
|
|
31
|
+
|
|
32
|
+
This is by design: `workflow_run` is intended for privileged workflows that
|
|
33
|
+
run in the base repository context regardless of where the triggering push came
|
|
34
|
+
from. It avoids giving fork PRs access to secrets — but it also means the
|
|
35
|
+
checkout behavior surprises developers expecting to test branch code.
|
|
36
|
+
|
|
37
|
+
The branch of the triggering workflow IS available via the event context:
|
|
38
|
+
`github.event.workflow_run.head_branch`
|
|
39
|
+
`github.event.workflow_run.head_sha`
|
|
40
|
+
|
|
41
|
+
fix: |
|
|
42
|
+
Explicitly set the `ref:` in your `actions/checkout` step to the triggering
|
|
43
|
+
workflow's head commit SHA or branch name.
|
|
44
|
+
|
|
45
|
+
Use `head_sha` (not `head_branch`) for more precise pinning — branch names
|
|
46
|
+
can advance between trigger and checkout for busy repositories.
|
|
47
|
+
|
|
48
|
+
fix_code:
|
|
49
|
+
- language: yaml
|
|
50
|
+
label: "Checkout the triggering workflow's exact commit"
|
|
51
|
+
code: |
|
|
52
|
+
on:
|
|
53
|
+
workflow_run:
|
|
54
|
+
workflows: ["CI — Unit Tests"]
|
|
55
|
+
types: [completed]
|
|
56
|
+
|
|
57
|
+
jobs:
|
|
58
|
+
deploy:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
with:
|
|
64
|
+
# Use head_sha for precise pinning — not head_branch
|
|
65
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
66
|
+
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: "Download artifacts from the triggering workflow run instead of re-checking out"
|
|
69
|
+
code: |
|
|
70
|
+
# For deployment workflows, prefer downloading the build artifact
|
|
71
|
+
# from the triggering run rather than re-building from source.
|
|
72
|
+
# This avoids the branch checkout problem entirely.
|
|
73
|
+
jobs:
|
|
74
|
+
deploy:
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/download-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
run-id: ${{ github.event.workflow_run.id }}
|
|
81
|
+
name: build-output
|
|
82
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
83
|
+
- name: Deploy
|
|
84
|
+
run: ./deploy.sh
|
|
85
|
+
|
|
86
|
+
- language: yaml
|
|
87
|
+
label: "Guard against running on wrong branch with a condition"
|
|
88
|
+
code: |
|
|
89
|
+
jobs:
|
|
90
|
+
deploy:
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
# Only deploy when triggered from the main branch to avoid
|
|
93
|
+
# accidentally deploying non-main code
|
|
94
|
+
if: |
|
|
95
|
+
github.event.workflow_run.conclusion == 'success' &&
|
|
96
|
+
github.event.workflow_run.head_branch == 'main'
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/checkout@v4
|
|
99
|
+
with:
|
|
100
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
101
|
+
|
|
102
|
+
prevention:
|
|
103
|
+
- "Always specify ref: ${{ github.event.workflow_run.head_sha }} in checkout steps inside workflow_run-triggered jobs."
|
|
104
|
+
- "Prefer downloading build artifacts over re-checking-out source code in workflow_run jobs to avoid branch confusion."
|
|
105
|
+
- "Log github.event.workflow_run.head_branch and head_sha at the start of workflow_run jobs for debugging."
|
|
106
|
+
- "Use the conclusion check (if: github.event.workflow_run.conclusion == 'success') to avoid deploying failed builds."
|
|
107
|
+
|
|
108
|
+
docs:
|
|
109
|
+
- url: "https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run"
|
|
110
|
+
label: "GitHub Docs — workflow_run event"
|
|
111
|
+
- url: "https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow"
|
|
112
|
+
label: "GitHub Docs — Using data from the triggering workflow"
|
|
113
|
+
- url: "https://stackoverflow.com/questions/76184351"
|
|
114
|
+
label: "SO#76184351 — workflow_run job runs on wrong (default) branch"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
id: yaml-syntax-024
|
|
2
|
+
title: "Reusable Workflow Nesting Exceeds Maximum Depth of 4 Levels"
|
|
3
|
+
category: yaml-syntax
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- reusable-workflow
|
|
7
|
+
- nesting
|
|
8
|
+
- depth-limit
|
|
9
|
+
- workflow_call
|
|
10
|
+
- yaml-parse-error
|
|
11
|
+
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "would exceed the limit on called workflow depth of \\d+"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "calls workflow .+, but doing so would exceed the limit"
|
|
16
|
+
flags: "i"
|
|
17
|
+
|
|
18
|
+
error_messages:
|
|
19
|
+
- "error parsing called workflow \"./.github/workflows/deploy.yml@\": job \"build\" calls workflow \"./.github/workflows/release.yml@\", but doing so would exceed the limit on called workflow depth of 3"
|
|
20
|
+
- "but doing so would exceed the limit on called workflow depth of 3"
|
|
21
|
+
|
|
22
|
+
root_cause: |
|
|
23
|
+
GitHub Actions enforces a maximum reusable workflow call depth of 4 levels total.
|
|
24
|
+
The top-level workflow counts as level 1, so the maximum number of sequential
|
|
25
|
+
workflow_call hops is 3 (levels 2, 3, and 4).
|
|
26
|
+
|
|
27
|
+
The error message says "depth of 3" because it refers to the maximum allowed
|
|
28
|
+
zero-indexed depth of called workflows, not the total chain length. When your
|
|
29
|
+
chain would require a 4th call (fifth total workflow), GitHub rejects the YAML
|
|
30
|
+
at parse time — before any runner picks up the job.
|
|
31
|
+
|
|
32
|
+
Example chain that fails:
|
|
33
|
+
root.yml → a.yml → b.yml → c.yml → d.yml (depth index 4 → rejected)
|
|
34
|
+
|
|
35
|
+
Example chain that succeeds:
|
|
36
|
+
root.yml → a.yml → b.yml → c.yml (depth index 3 → allowed)
|
|
37
|
+
|
|
38
|
+
This limit was increased from 2 to 3 in August 2022 and is currently fixed at 4
|
|
39
|
+
total levels (depth index 0–3).
|
|
40
|
+
|
|
41
|
+
fix: |
|
|
42
|
+
Reduce the nesting depth so the total chain is 4 levels or fewer.
|
|
43
|
+
Strategies:
|
|
44
|
+
|
|
45
|
+
1. Flatten: merge two deeply-nested reusable workflows into one.
|
|
46
|
+
2. Convert inner reusables to composite actions — composite actions do NOT
|
|
47
|
+
count toward the reusable workflow depth limit.
|
|
48
|
+
3. Restructure so leaf workflows are composite actions, keeping reusable
|
|
49
|
+
workflows only at the top layers.
|
|
50
|
+
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: "Replace inner reusable workflow with a composite action"
|
|
54
|
+
code: |
|
|
55
|
+
# Instead of calling another reusable workflow at depth 4,
|
|
56
|
+
# use a composite action in .github/actions/my-task/action.yml
|
|
57
|
+
# which has no depth limit.
|
|
58
|
+
|
|
59
|
+
# .github/actions/my-task/action.yml
|
|
60
|
+
name: My Task
|
|
61
|
+
description: Previously a reusable workflow, now a composite action
|
|
62
|
+
runs:
|
|
63
|
+
using: composite
|
|
64
|
+
steps:
|
|
65
|
+
- name: Do the work
|
|
66
|
+
shell: bash
|
|
67
|
+
run: echo "doing the work"
|
|
68
|
+
|
|
69
|
+
# Called from the deeply-nested workflow:
|
|
70
|
+
- name: Run my task
|
|
71
|
+
uses: ./.github/actions/my-task # composite, no depth counted
|
|
72
|
+
|
|
73
|
+
- language: yaml
|
|
74
|
+
label: "Flatten two reusable workflows into one to reduce depth"
|
|
75
|
+
code: |
|
|
76
|
+
# Before (depth 4 — fails):
|
|
77
|
+
# root.yml → build.yml → test.yml → lint.yml → scan.yml
|
|
78
|
+
#
|
|
79
|
+
# After (depth 3 — passes):
|
|
80
|
+
# Merge lint.yml and scan.yml into a single quality.yml
|
|
81
|
+
|
|
82
|
+
# quality.yml
|
|
83
|
+
on:
|
|
84
|
+
workflow_call:
|
|
85
|
+
inputs:
|
|
86
|
+
target:
|
|
87
|
+
required: true
|
|
88
|
+
type: string
|
|
89
|
+
jobs:
|
|
90
|
+
lint:
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
- run: echo "linting ${{ inputs.target }}"
|
|
95
|
+
scan:
|
|
96
|
+
runs-on: ubuntu-latest
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/checkout@v4
|
|
99
|
+
- run: echo "scanning ${{ inputs.target }}"
|
|
100
|
+
|
|
101
|
+
prevention:
|
|
102
|
+
- "Map your reusable workflow call chain before writing YAML — count total levels."
|
|
103
|
+
- "Prefer composite actions for leaf-level tasks; they have no depth limit."
|
|
104
|
+
- "Limit reusable workflow use to high-value shared orchestration layers, not every step."
|
|
105
|
+
- "If depth 4 is genuinely required, consider splitting the pipeline into separate triggered workflows using workflow_run instead of nested workflow_call."
|
|
106
|
+
|
|
107
|
+
docs:
|
|
108
|
+
- url: "https://docs.github.com/en/actions/using-workflows/reusing-workflows#nesting-reusable-workflows"
|
|
109
|
+
label: "GitHub Docs — Nesting reusable workflows"
|
|
110
|
+
- url: "https://github.blog/changelog/2022-08-22-github-actions-improvements-to-reusable-workflows-2/"
|
|
111
|
+
label: "GitHub Changelog — Nesting increased to 4 levels (August 2022)"
|
|
112
|
+
- url: "https://github.com/actions/runner/issues/1797"
|
|
113
|
+
label: "actions/runner#1797 — Original depth-limit enhancement request"
|
package/package.json
CHANGED