Repository navigation
gh run list does not work with organization ruleset required workflows #10076
Description
Activity
- changed the title
[-]gh ru with github enterprise does not work[/-][+]`gh run` with github enterprise does not work[/+]on Dec 13, 2024 - addedgh-runrelating to the gh run commandrelating to the gh run command
on Dec 13, 2024 Here's a little more detail on that request if that helps as well
$ GH_DEBUG=api gh run list [git remote -v] [git config --get-regexp ^remote\..*\.gh-resolved$] * Request at 2024-12-13 00:25:12.490931 -0600 CST m=+0.142628668 * Request to https://{GHE_SERVER_URL}/api/graphql > POST /api/graphql HTTP/1.1 > Host: {GHE_SERVER_URL} > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token xxxxxxxxxxxxxxxxx > Content-Length: 403 > Content-Type: application/json; charset=utf-8 > Graphql-Features: merge_queue > Time-Zone: America/Chicago > User-Agent: GitHub CLI 2.63.2 GraphQL query: fragment repo on Repository { id name owner { login } viewerPermission defaultBranchRef { name } isPrivate } query RepositoryNetwork { viewer { login } repo_000: repository(owner: "{ORG}", name: "{REPO}") { ...repo parent { ...repo } } } GraphQL variables: null < HTTP/2.0 200 OK < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Fri, 13 Dec 2024 06:25:12 GMT < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains < X-Accepted-Oauth-Scopes: repo < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Enterprise-Version: 3.13.4 < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: 2d6be83a-42e4-4277-86ee-17e503b72063 < X-Oauth-Client-Id: xxxxxxxxx < X-Oauth-Scopes: admin:org, gist, repo, workflow < X-Ratelimit-Limit: 5000 < X-Ratelimit-Remaining: 5000 < X-Ratelimit-Reset: 1734074712 < X-Ratelimit-Resource: graphql < X-Ratelimit-Used: 0 < X-Xss-Protection: 0 { "data": { "viewer": { "login": "Ezbon-Jacob" }, "repo_000": { "id": "MDEwOlJlcG9zaXRvcnkxMzI3NQ==", "name": "{REPO}", "owner": { "login": "{ORG}" }, "viewerPermission": "ADMIN", "defaultBranchRef": { "name": "main" }, "isPrivate": false, "parent": null } } } * Request took 479.094833ms ⣾* Request at 2024-12-13 00:25:13.020862 -0600 CST m=+0.672553668 * Request to https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/runs?per_page=20&exclude_pull_requests=true > GET /api/v3/repos/{ORG}/{REPO}/actions/runs?per_page=20&exclude_pull_requests=true HTTP/1.1 > Host: {GHE_SERVER_URL} > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token xxxxxxxxxxxxxxxxx > Content-Type: application/json; charset=utf-8 > Time-Zone: America/Chicago > User-Agent: GitHub CLI 2.63.2 ⣯< HTTP/2.0 200 OK < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Cache-Control: private, max-age=60, s-maxage=60 < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Fri, 13 Dec 2024 06:25:13 GMT < Etag: W/"7bd1cd387f53f14ccca12fa072d08f08e04c7479bddc0080c6281f731c662b1c" < Link: <https://{GHE_SERVER_URL}/api/v3/repositories/13275/actions/runs?per_page=20&exclude_pull_requests=true&page=2>; rel="next", <https://{GHE_SERVER_URL}/api/v3/repositories/13275/actions/runs?per_page=20&exclude_pull_requests=true&page=1785>; rel="last" < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains < Vary: Accept, Authorization, Cookie, X-GitHub-OTP < X-Accepted-Oauth-Scopes: < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Api-Version-Selected: 2022-11-28 < X-Github-Enterprise-Version: 3.13.4 < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: 8b00d54f-5d28-47ef-a18d-83f7a6292c5a < X-Oauth-Client-Id: xxxxxxxxx < X-Oauth-Scopes: admin:org, gist, repo, workflow < X-Xss-Protection: 0 * body is too long, skipping (contains more than 100000 bytes) * Request took 714.963792ms * Request at 2024-12-13 00:25:13.77722 -0600 CST m=+1.428904126 * Request to https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows?per_page=100&page=1 > GET /api/v3/repos/{ORG}/{REPO}/actions/workflows?per_page=100&page=1 HTTP/1.1 > Host: {GHE_SERVER_URL} > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token xxxxxxxxxxxxxxxxx > Content-Type: application/json; charset=utf-8 > Time-Zone: America/Chicago > User-Agent: GitHub CLI 2.63.2 ⣾< HTTP/2.0 200 OK < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Cache-Control: private, max-age=60, s-maxage=60 < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Fri, 13 Dec 2024 06:25:13 GMT < Etag: W/"4b6f9372857cab41a17b1bacc564ec5aeede364c81f05d224100b244cf397b14" < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains < Vary: Accept, Authorization, Cookie, X-GitHub-OTP < X-Accepted-Oauth-Scopes: < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Api-Version-Selected: 2022-11-28 < X-Github-Enterprise-Version: 3.13.4 < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: 34ca2185-defd-4468-a784-53c75f353033 < X-Oauth-Client-Id: xxxxxxxxx < X-Oauth-Scopes: admin:org, gist, repo, workflow < X-Xss-Protection: 0 { "total_count": 5, "workflows": [ { "id": 4548, "node_id": "MDg6V29ya2Zsb3c0NTQ4", "name": "⬆ Check Dependencies", "path": ".github/workflows/check-dependencies.yml", "state": "active", "created_at": "2022-05-02T09:31:31.000-05:00", "updated_at": "2024-06-06T13:12:01.000-05:00", "url": "https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/4548", "html_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/check-dependencies.yml", "badge_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/workflows/%E2%AC%86%EF%B8%8F%20Check%20Dependencies/badge.svg" }, { "id": 4549, "node_id": "MDg6V29ya2Zsb3c0NTQ5", "name": "Build Docker Image", "path": ".github/workflows/docker-build.yml", "state": "active", "created_at": "2022-05-02T09:31:31.000-05:00", "updated_at": "2022-05-02T09:31:31.000-05:00", "url": "https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/4549", "html_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/docker-build.yml", "badge_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/workflows/Build%20Docker%20Image/badge.svg" }, { "id": 3991, "node_id": "MDg6V29ya2Zsb3czOTkx", "name": "🧹 Lint Code Base", "path": ".github/workflows/linter.yml", "state": "active", "created_at": "2022-04-25T11:14:21.000-05:00", "updated_at": "2024-03-15T17:16:45.000-05:00", "url": "https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/3991", "html_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/linter.yml", "badge_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/workflows/%F0%9F%A7%B9%20Lint%20Code%20Base/badge.svg" }, { "id": 74638, "node_id": "MDg6V29ya2Zsb3c3NDYzOA==", "name": "🛡 Build & Submit Security Scan", "path": ".github/workflows/security-scan.yml", "state": "active", "created_at": "2024-11-14T16:38:37.000-06:00", "updated_at": "2024-11-14T16:38:37.000-06:00", "url": "https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/74638", "html_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/security-scan.yml", "badge_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/workflows/%F0%9F%9B%A1%EF%B8%8F%20Build%20&%20Submit%20Security%20Scan/badge.svg" }, { "id": 3992, "node_id": "MDg6V29ya2Zsb3czOTky", "name": "🏃🏽♂ Unit Tests & Behavior Tests", "path": ".github/workflows/testing.yml", "state": "active", "created_at": "2022-04-25T11:14:21.000-05:00", "updated_at": "2024-03-15T17:16:45.000-05:00", "url": "https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/3992", "html_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/testing.yml", "badge_url": "https://{GHE_SERVER_URL}/{ORG}/{REPO}/workflows/%F0%9F%8F%83%F0%9F%8F%BD%E2%80%8D%E2%99%82%EF%B8%8F%20Unit%20Tests%20&%20Behavior%20Tests/badge.svg" } ] } * Request took 190.806084ms * Request at 2024-12-13 00:25:14.014859 -0600 CST m=+1.666541460 * Request to https://{GHE_SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/63737 > GET /api/v3/repos/{ORG}/{REPO}/actions/workflows/63737 HTTP/1.1 > Host: {GHE_SERVER_URL} > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token xxxxxxxxxxxxxxxxx > Content-Type: application/json; charset=utf-8 > Time-Zone: America/Chicago > User-Agent: GitHub CLI 2.63.2 ⣽< HTTP/2.0 404 Not Found < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Fri, 13 Dec 2024 06:25:14 GMT < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains < X-Accepted-Oauth-Scopes: < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Api-Version-Selected: 2022-11-28 < X-Github-Enterprise-Version: 3.13.4 < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: a56f76a9-383a-49eb-9974-248572f7200f < X-Oauth-Client-Id: xxxxxxxxx < X-Oauth-Scopes: admin:org, gist, repo, workflow < X-Xss-Protection: 0 { "message": "Not Found", "documentation_url": "https://docs.github.com/[email protected]/rest/actions/workflows#get-a-workflow" }Hey @codezninja,
Not clear on what's going on here. The request that is 404ing:
https://{SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/63737Is coming from here:
cli/pkg/cmd/run/shared/shared.go
Line 446 in c789b56
workflow, err := workflowShared.GetWorkflow(client, repo, run.WorkflowID) The logic surrounding this is:
- Fetch the list of runs
- Fetch all the workflows in order to get their name
- If a workflow isn't in the list of workflows, it's probably been deleted so make a request for it directly
So I wouldn't expect the ID you see here to be in the output of
workflow listwhich only show undeleted workflows. However, I also wouldn't expect it to 404, since a deleted workflow is handled by the API in thestatefield:https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28#get-a-workflow
Does anything about this jump out to you? I need to think about it a bit more.
Haha snap timing 😅 Thank you for the extra details.
Reacted by Ezbon JacobWhat kind of token are you using? OAuth? Legacy PAT? Fine-grained PAT?
What kind of token are you using? OAuth? Legacy PAT? Fine-grained PAT?
@williammartin so I'm using OAuth token here these are the scopes I have as well
Token scopes: 'admin:org', 'gist', 'repo', 'workflow'Are you able to hit any of the other workflow GET endpoints e.g.?
gh api https://{SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/4548I took
4548from the first result in your list workflow http response.yeah when the workflow id is right I'm getting a response
$ gh api repos/{ORG}/{REPO}/actions/workflows/4548 { "id": 4548, "node_id": "MDg6V29ya2Zsb3c0NTQ4", "name": "⬆ Check Dependencies", "path": ".github/workflows/check-dependencies.yml", "state": "active", "created_at": "2022-05-02T09:31:31.000-05:00", "updated_at": "2024-06-06T13:12:01.000-05:00", "url": "https://{SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/workflows/4548", "html_url": "https://{SERVER_URL}/{ORG}/{REPO}/blob/main/.github/workflows/check-dependencies.yml", "badge_url": "https://{SERVER_URL}/{ORG}/{REPO}/workflows/%E2%AC%86%EF%B8%8F%20Check%20Dependencies/badge.svg" }I've also done a test with all the workflows returning from the workflow list id and I get a response for each one
gh workflow list --json id -q '.[] | .id' | xargs -I {} gh api repos/{ORG}/{REPO}/actions/workflows/{}
👋 Hey @codezninja
@williammartin and I discussed this internally with the Actions platform team, and we think this is another case of #9228 - the workflow is a "required workflow" and isn't actually owned by this repo. It is actually stored in a different repository and shared out across the organization, but this API endpoint is repo-specific and so it 404s.
The response you got from listing the runs is truncated because it is too long, but if we were able to see the full response, I suspect we would see something like the following, which indicates the 404'ing workflow is a "required workflow".
GET /api/v3/repos/{ORG}/{REPO}/actions/runs?per_page=20&exclude_pull_requests=true HTTP/1.1
"workflow_url": "https://<GHES>/repos/<ORG>/<REPO-STORING-REQUIRED-WORKFLOWS>/actions/required_workflows/41288899",
If you want to confirm, get the full output from that listing, and look for the
63737ID in the output - or just search for/required_workflows/, and I suspect you will find this and other workflow runs that would 404:gh api https://{SERVER_URL}/api/v3/repos/{ORG}/{REPO}/actions/runs --method GET -f per_page=20 -f page=1Note
You could also use the
--paginateoption ongh api, but be careful with the rate-limiting that may occur on busy repos. I would recommend just adjusting the page parameters.
@williammartin I think we need to handle these somehow, but there's problems that I don't know how we would overcome:
- The API doesn't seem to indicate which repository the workflow is stored in; it could be any repo in the organization. All we seem to have is that it is "required" based on the
workflow_urlvalue. - That
workflow_urlthat we do get doesn't seem to be intended for long term use. If you hit that workflow endpoint, you get a response like the following, which is both unhelpful and indicates that the value may not be reliable long term:422 Unprocessable Entity As of GHES 3.12, this feature is fully deprecated and creating required workflows is only available with repository rulesets. All existing workflows have been automatically migrated to rulesets. Learn more about rulesets: https://github.blog/2023-10-11-enforcing-code-reliability-by-requiring-workflows-with-github-repository-rules/ - I don't think it's a good idea to request info directly about the ruleset because the endpoint I believe we'd need to use requires
admin: orgscopes 😕 I don't think we want to require that scope forgh run listto work in cases with rulesets.
If we knew which repo the workflow was in, I think it might be reasonable for us to simply adjust which repository we request the workflow details from because the repo storing the required workflow will match the visibility of the repo we're viewing runs for. Except in the case of private visibility, in which case if we were to still 404 on requested workflow, we'd have to still handle it like the workflow exists but the user can't access it.
But all that is just speculation about if we had some way to know what repo the workflow is in 😅 which we do not currently have AFACT.
In lieu of something in the API that would allow us to really "fix" this by requesting the workflow details from the correct repository, maybe all we can do is assume a 404 means this run is "external" and mark it as such, avoiding a complete command failure.
- The API doesn't seem to indicate which repository the workflow is stored in; it could be any repo in the organization. All we seem to have is that it is "required" based on the
- addedmore-info-neededMore info needed from user/contributorMore info needed from user/contributorpriority-2Affects more than a few users but doesn't prevent core functionsAffects more than a few users but doesn't prevent core functions
on Dec 16, 2024 ahh yes @BagToad you are right. I know this repos have a few org rulesets that require some workflows to run so that totally makes sense. I confirmed that run is tied to the required workflow at the org level.
Let me know if you need anything else
Reacted by Kynan WareAcceptance Criteria
Given I there is a
runwhose workflow is required via an org ruleset
When I rungh run list
Then Under theWORKFLOWcolumn I see no entry.When I run
gh run list --help
Then I see an explanation of what no entry means.Given I there is a
runwhose workflow is required via an org ruleset
When I rungh run list --json workflowName
Then I seenilfor the value ofworkflowNameI'm choosing
nilbecause when programmatically interpreting this, it should not be confused with any other name.When I run
gh run list --help
Then I see an explanation that theworkflowNamefield may be nil in this caseNote: Need to understand whether we have
workflowDatabaseIdjson field.
This is not ideal, but is a strict improvement that means the command isn't straight up broken, and highlights the current deficiencies that we can improve on later if we have a solution, without introducing any obvious breaking changes later.
Reacted by Kynan Ware- addedhelp wantedContributions welcomeContributions welcomeand removedmore-info-neededMore info needed from user/contributorMore info needed from user/contributorneeds-triageneeds to be reviewedneeds to be reviewed
on Dec 16, 2024 - changed the title
[-]`gh run` with github enterprise does not work[/-][+]`gh run` does not work with organization ruleset required workflows[/+]on Dec 16, 2024 - changed the title
[-]`gh run` does not work with organization ruleset required workflows[/-][+]`gh run list` does not work with organization ruleset required workflows[/+]on Dec 16, 2024
Describe the bug
Similar bug mentioned #3437, but gh run view or list all return a 404. The URL returned seems right based on REST api docs but not getting any response. When comparing the ID
gh run listdoesn't seem to be correct based on the ids fromgh workflow listgh cli version:
gh version 2.63.2 (2024-12-05)ghe version:
3.13.4Steps to reproduce the behavior
Expected vs actual behavior
The gh run list prints out list of workflow runs for the repo to choose from
Logs