Skip to content

Commit 52ee51b

Browse files
committed
Support self-repository external references
Resolve $/ paths in downloaded reusable workflows and composite actions against their modeled repository, and cover both forms while retaining ./ compatibility.
1 parent f3f6b42 commit 52ee51b

6 files changed

Lines changed: 43 additions & 11 deletions

File tree

actions/ql/lib/codeql/actions/ast/internal/Ast.qll

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,11 @@ class UsesStepImpl extends StepImpl, UsesImpl {
14411441
else result = u.getValue()
14421442
}
14431443

1444-
private predicate isLocalCall() { u.getValue().matches(["./%", ".github/%"]) }
1444+
private predicate isWorkspaceLocalCall() { u.getValue().matches(["./%", ".github/%"]) }
1445+
1446+
private predicate isSelfCall() { u.getValue().matches("$/%") }
1447+
1448+
private predicate isLocalCall() { this.isWorkspaceLocalCall() or this.isSelfCall() }
14451449

14461450
private predicate hasModeledExternalCallee() {
14471451
exists(
@@ -1473,15 +1477,36 @@ class UsesStepImpl extends StepImpl, UsesImpl {
14731477
)
14741478
}
14751479

1480+
private string getSelfCallableName() {
1481+
exists(
1482+
CompositeActionImpl action, string owner, string repo, string action_path,
1483+
string requested_ref, string resolved_commit_sha, string local_path
1484+
|
1485+
action = this.getEnclosingCompositeAction() and
1486+
action
1487+
.getAnExternalCompositeActionModel(owner, repo, action_path, requested_ref,
1488+
resolved_commit_sha, local_path) and
1489+
result =
1490+
externalCompositeActionName(owner, repo, this.getCallee().suffix(2)) + "@" +
1491+
requested_ref.trim()
1492+
)
1493+
or
1494+
not this.hasExternalEnclosingCompositeAction() and
1495+
result = this.getCallee().suffix(2)
1496+
}
1497+
14761498
override string getCallableName() {
1477-
this.isLocalCall() and
1499+
this.isWorkspaceLocalCall() and
14781500
(
14791501
this.hasModeledExternalEnclosingCompositeAction()
14801502
or
14811503
not this.hasExternalEnclosingCompositeAction()
14821504
) and
14831505
result = this.getCallee()
14841506
or
1507+
this.isSelfCall() and
1508+
result = this.getSelfCallableName()
1509+
or
14851510
not this.isLocalCall() and
14861511
this.hasModeledExternalCallee() and
14871512
result = this.getCallee() + "@" + this.getVersion()
@@ -1501,28 +1526,27 @@ class UsesStepImpl extends StepImpl, UsesImpl {
15011526
* Gets a regular expression that parses an `owner/repo@version` reference within a `uses` field in an Actions job step.
15021527
* local repo: octo-org/this-repo/.github/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89
15031528
* local repo: ./.github/workflows/workflow-2.yml
1529+
* local repo: $/.github/workflows/workflow-2.yml
15041530
* remote repo: octo-org/another-repo/.github/workflows/workflow.yml@v1
15051531
*/
15061532
private string repoUsesParser() { result = "([^/]+)/([^/]+)/([^@]+)@(.+)" }
15071533

1508-
private string pathUsesParser() { result = "\\./(.+)" }
1509-
15101534
class ExternalJobImpl extends JobImpl, UsesImpl {
15111535
YamlScalar u;
15121536

15131537
ExternalJobImpl() { n.lookup("uses") = u }
15141538

15151539
override string getCallee() {
1516-
if u.getValue().matches("./%")
1517-
then result = u.getValue().regexpCapture(pathUsesParser(), 1)
1540+
if u.getValue().matches(["./%", "$/%"])
1541+
then result = u.getValue().suffix(2)
15181542
else
15191543
result =
15201544
u.getValue().regexpCapture(repoUsesParser(), 1) + "/" +
15211545
u.getValue().regexpCapture(repoUsesParser(), 2) + "/" +
15221546
u.getValue().regexpCapture(repoUsesParser(), 3)
15231547
}
15241548

1525-
private predicate isLocalCall() { u.getValue().matches("./%") }
1549+
private predicate isLocalCall() { u.getValue().matches(["./%", "$/%"]) }
15261550

15271551
private predicate hasExternalEnclosingWorkflow() {
15281552
exists(ReusableWorkflowImpl enclosing_workflow |

actions/ql/test/external-reusable-workflows.model.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ extensions:
2020
data:
2121
- ["TestOrg", "Actions", "remote", "v1", "dddddddddddddddddddddddddddddddddddddddd", "9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-0wu7t20oora8i/remote/action.yml"]
2222
- ["TestOrg", "Actions", "remote", "v2", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/remote/action.yml"]
23+
- ["TestOrg", "Actions", ".github/actions/leaf", "v2", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/.github/actions/leaf/action.yml"]
2324
- ["TestOrg", "TestRepo", ".github/actions/clone-repo", "main", "1111111111111111111111111111111111111111", "9466014afba34ef28239871ceabf4132/TestOrg/TestRepo/ref-07cp61dt7qne3/.github/actions/clone-repo/action.yaml"]
2425
- ["ultralytics", "actions", "", "main", "2222222222222222222222222222222222222222", "9466014afba34ef28239871ceabf4132/ultralytics/actions/ref-07cp61dt7qne3/action.yaml"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: External leaf action at v2
2+
description: Completes a self-repository action chain
3+
runs:
4+
using: composite
5+
steps:
6+
- shell: bash
7+
run: echo complete
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: External action at v2
2-
description: Calls back into the analyzed repository
2+
description: Calls an action in the same external repository
33
runs:
44
using: composite
55
steps:
6-
- uses: ./.github/actions/leaf
6+
- uses: $/.github/actions/leaf

actions/ql/test/library-tests/external-composite-actions/external_composite_actions.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
| 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-0wu7t20oora8i/remote/action.yml:6:7:6:35 | Uses Step | ./.github/actions/leaf | | .github/actions/leaf/action.yml |
2-
| 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/remote/action.yml:6:7:6:35 | Uses Step | ./.github/actions/leaf | | .github/actions/leaf/action.yml |
2+
| 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/remote/action.yml:6:7:6:35 | Uses Step | $/.github/actions/leaf | | 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/.github/actions/leaf/action.yml |
33
| .github/actions/root-v1/action.yml:6:7:6:38 | Uses Step | TestOrg/Actions/remote | v1 | 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-0wu7t20oora8i/remote/action.yml |
44
| .github/actions/root-v2/action.yml:6:7:6:38 | Uses Step | TestOrg/Actions/remote | v2 | 9466014afba34ef28239871ceabf4132/TestOrg/Actions/ref-3tf7yq1278i0t/remote/action.yml |
55
| .github/workflows/caller.yml:10:9:11:6 | Uses Step | ./.github/actions/root-v1 | | .github/actions/root-v1/action.yml |

actions/ql/test/library-tests/external-reusable-workflows/9466014afba34ef28239871ceabf4132/TestOrg/TestRepo/ref-3tf7yq1278i0t/.github/workflows/first.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ on:
55

66
jobs:
77
second:
8-
uses: ./.github/workflows/second.yml
8+
uses: $/.github/workflows/second.yml

0 commit comments

Comments
 (0)