Skip to content

🤬 API and Events Rant 🤬 #354

Closed
@MariusStorhaug

Description

@MariusStorhaug

API

Regarding pwsh function to API alignments, check this issue:
🌞 [Other]: API to function mapping redesign #278

Rate limits - when it fails its status code is 403 or 422, not 429

Also, where is the 'Retry-After' ?

Primary rate limits - 403, not 429

Invoke-GitHubAPI : ----------------------------------
Request:

Headers        : {[User-Agent, PSModule.GitHub 999.0.0], [Accept, application/vnd.github+json; charset=utf-8], [X-GitHub-Api-Version, 2022-11-28]}
HttpVersion    : 2.0
Method         : PUT
Uri            : https://api.github.com/repos/limit-test/limit-test/environments/env-1347aa66-755f-4fc1-8e73-3c136a2e9bdd
ContentType    : application/vnd.github+json; charset=utf-8
Authentication : Bearer
Token          : System.Security.SecureString


----------------------------------
Body:

----------------------------------
Response Headers:

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'
Date                                   : 2025-05-25T19:32:10
github-authentication-token-expiration : 2025-05-26T02:23:47
Referrer-Policy                        : origin-when-cross-origin, strict-origin-when-cross-origin
Server                                 : github.com
Strict-Transport-Security              : max-age=31536000; includeSubdomains; preload
Vary                                   : Accept-Encoding, Accept, X-Requested-With
x-accepted-oauth-scopes                : repo
X-Content-Type-Options                 : nosniff
X-Frame-Options                        : deny
x-github-media-type                    : github.v3; format=json
x-github-request-id                    : ECA6:BC6E6:5713888:5A361B5:6833541A
x-oauth-client-id                      : Iv1.f26b61bc99e69405
x-oauth-scopes                         : 
x-ratelimit-limit                      : 15000
x-ratelimit-remaining                  : 0
x-ratelimit-reset                      : 2025-05-25T19:56:37
x-ratelimit-resource                   : core
x-ratelimit-used                       : 15012
X-XSS-Protection                       : 0


----------------------------------
Error:

Message     : API rate limit exceeded for user ID 17722253. If you reach out to GitHub Support for help, please include the request ID ECA6:BC6E6:5713888:5A361B5:6833541A and timestamp 2025-05-25 17:32:10 UTC.
Resource    : 
Code        : 
Details     : 
Information : https://docs.github.com/rest/overview/rate-limits-for-the-rest-api
Status      : Response status code does not indicate success: 403 (Forbidden).
StatusCode  : 403
ErrorTime   : 2025-05-25T19:32:10

----------------------------------

Secondary rate limits - 403 + no Retry-After

Why doesnt a ratelimit respond with a 429?

Invoke-GitHubAPI : ----------------------------------
Request:

Headers        : {[User-Agent, PSModule.GitHub 999.0.0], [Accept, application/vnd.github+json; charset=utf-8], [X-GitHub-Api-Version, 2022-11-28]}
HttpVersion    : 2.0
Method         : POST
Uri            : https://api.github.com/orgs/limit-test/repos
ContentType    : application/vnd.github+json; charset=utf-8
Authentication : Bearer
Token          : System.Security.SecureString


----------------------------------
Body:

----------------------------------
Response Headers:

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'
Date                                   : 2025-05-25T19:21:54
github-authentication-token-expiration : 2025-05-26T02:23:47
Referrer-Policy                        : origin-when-cross-origin, strict-origin-when-cross-origin
Server                                 : github.com
Strict-Transport-Security              : max-age=31536000; includeSubdomains; preload
Vary                                   : Accept-Encoding, Accept, X-Requested-With
x-accepted-github-permissions          : administration=write
x-accepted-oauth-scopes                : public_repo, repo
X-Content-Type-Options                 : nosniff
X-Frame-Options                        : deny
x-github-api-version-selected          : 2022-11-28
x-github-media-type                    : github.v3; format=json
x-github-request-id                    : E19B:3E4C31:56FC9A7:5A1B49F:683351B2
x-oauth-client-id                      : Iv1.f26b61bc99e69405
x-oauth-scopes                         : 
x-ratelimit-limit                      : 15000
x-ratelimit-remaining                  : 742
x-ratelimit-reset                      : 2025-05-25T19:56:37
x-ratelimit-resource                   : core
x-ratelimit-used                       : 14258
X-XSS-Protection                       : 0


----------------------------------
Error:

Message     : You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later. If you reach out to GitHub Support for help, please include the request ID E19B:3E4C31:56FC9A7:5A1B49F:683351B2 and timestamp 2025-05-25 17:21:54 UTC.
Resource    : 
Code        : 
Details     : 
Information : https://docs.github.com/rest/overview/rate-limits-for-the-rest-api#about-secondary-rate-limits
Status      : Response status code does not indicate success: 403 (Forbidden).
StatusCode  : 403
ErrorTime   : 2025-05-25T19:21:54


----------------------------------

Create repo from Template - 422, no Retry-After

Exception: ----------------------------------
Request:
Uri : https://api.github.com/repos/PSModule/Template-Docs/generate
MaximumRetryCount : 0
Method : POST
RetryIntervalSec : 1
Token : System.Security.SecureString
ContentType : application/vnd.github+json; charset=utf-8
Authentication : Bearer
HttpVersion : 2.0

Request headers:
Accept : application/vnd.github+json; charset=utf-8
X-GitHub-Api-Version : 2022-11-28
User-Agent : PSModule.GitHub 999.0.0

Request body:
{
"include_all_branches": false,
"private": false,
"name": "RepositoriesTests-Windows-PAT-9479aafa-975b-4cf3-961b-134d708e8190-template"
}

Response headers:
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'
Date : 2025-06-09T08:06:21
Referrer-Policy : origin-when-cross-origin, strict-origin-when-cross-origin
Server : github.com
Strict-Transport-Security : max-age=31536000; includeSubdomains; preload
Vary : Accept-Encoding, Accept, X-Requested-With
x-accepted-oauth-scopes :
X-Content-Type-Options : nosniff
X-Frame-Options : deny
x-github-api-version-selected : 2022-11-28
x-github-media-type : github.v3; format=json
x-github-request-id : D415:325AE5:6E33725:E02B2C4:684695FD
x-oauth-scopes : admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, admin:ssh_signing_key, audit_log, codespace, copilot, delete:packages, delete_repo, gist, notifications, project, repo, user, workflow, write:discussion, write:network_configurations, write:packages
x-ratelimit-limit : 5000
x-ratelimit-remaining : 101
x-ratelimit-reset : 2025-06-09T08:56:39
x-ratelimit-resource : core
x-ratelimit-used : 4899
X-XSS-Protection : 0

Error:
Message : Could not clone: was submitted too quickly
Resource :
Code :
Details :
Information : https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template
Status : Response status code does not indicate success: 422 (Unprocessable Entity).
StatusCode : 422
ErrorTime : 2025-06-09T08:06:21

Fork a repo - 403 + no Retry-After

Exception: ----------------------------------
Request:
Uri : https://api.github.com/repos/psmodule-test/fork-Windows/forks
MaximumRetryCount : 0
Method : POST
RetryIntervalSec : 1
Token : System.Security.SecureString
ContentType : application/vnd.github+json; charset=utf-8
Authentication : Bearer
HttpVersion : 2.0

Request headers:
Accept : application/vnd.github+json; charset=utf-8
X-GitHub-Api-Version : 2022-11-28
User-Agent : PSModule.GitHub 999.0.0

Request body:
{
"default_branch_only": true,
"name": "RepositoriesTests-Windows-PAT-9479aafa-975b-4cf3-961b-134d708e8190-fork3"
}

Response headers:
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'
Date : 2025-06-09T08:06:23
Referrer-Policy : origin-when-cross-origin, strict-origin-when-cross-origin
Server : github.com
Strict-Transport-Security : max-age=31536000; includeSubdomains; preload
Vary : Accept-Encoding, Accept, X-Requested-With
x-accepted-oauth-scopes :
X-Content-Type-Options : nosniff
X-Frame-Options : deny
x-github-api-version-selected : 2022-11-28
x-github-media-type : github.v3; format=json
x-github-request-id : D412:244AFD:789D5EF:F4CCDDA:684695FF
x-oauth-scopes : admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, admin:ssh_signing_key, audit_log, codespace, copilot, delete:packages, delete_repo, gist, notifications, project, repo, user, workflow, write:discussion, write:network_configurations, write:packages
x-ratelimit-limit : 5000
x-ratelimit-remaining : 99
x-ratelimit-reset : 2025-06-09T08:56:39
x-ratelimit-resource : core
x-ratelimit-used : 4901
X-XSS-Protection : 0

Error:
Message : was submitted too quickly
Resource :
Code :
Details :
Information : https://docs.github.com/rest/repos/forks#create-a-fork
Status : Response status code does not indicate success: 403 (Forbidden).
StatusCode : 403
ErrorTime : 2025-06-09T08:06:23

Repositories

Repositories - Create repo + base settings

Base (changable) settings include Visibility, Homepage, IsTemplate, IsArchived, RequireWebCommitSignoff, Description, DefaultBranch, HasWiki, HasIssues, HasDiscussions, HasProjects, AllowMergeCommit, AllowSquashMerge, AllowRebaseMerge, AllowAutoMerge, SuggestUpdateBranch, DeleteBranchOnMerge

GQL REST - User REST - Org REST - Fork REST - Template
Link Link Link Link Link
A very limited set of base settings Almost full set of settings, missing hasSponsorships Almost full set of settings, missing hasSponsorships No settings on endpoint, allowed to be changed by platform. Visibility is unchangeable from parent (disallowed by platform). Only name, private and description settings available, not allowing to set internal visibility. No other base settings on endpoint, even though its allowed by platform.

⚠️ Warning!
None of these have support for "Preserve this repository", "Include Git LFS objects in archives", "Limit how many branches and tags can be updated in a single push" or "Auto-close issues with merged linked pull requests Loading".

Can only use REST for creating from Fork or Template.
These cannot configure settings.

Conclusion:
Create repo using the following flow:

  1. Create repo with REST.
  2. Update repo with different API calls.
  3. Return the result from a GraphQL Query.

Repositories - Create has no defaultBranch on GraphQL ?

Create with REST API, shows that it exists.

Image

Update with GraphQL doesnt return it...

Image

Image

Repositories - Duplicates - Counters

Image

Repositories - Objects in GraphQL

Inconsistent verb-noun usage

Image

Repositories - Duplicates - Private or visibility?

The same data is also stored on the object. It has private and visibility. When a repo is private, you can see this with both private: true and visibility: 'private'

Image

Repositories - Fork vs Template

Fork Template
Image Image

Repositories - Create - REST vs GraphQL

REST GraphQL
REST API has 'has_downloads' which i think is deprecated? This is missing 'has_sponsorship' GraphQL: Create only has 'hasWikiEnabled' and 'hasIssuesEnabled'
Image Image

GraphQL: Update has all the expected things i guess. Has sponsorship, and not downloads (which i assume is deprecated)
Image

Secrets & Variables - 'C' + 'U' vs 'C||U'

Image

General - List of items

List variables List repositories
{ "count": 3, "variables": [ {...},{...},{...} ] [ {...} ]
Image Image

Organization - Create

Only available as a GraphQL mutation!

REST GraphQL
Image Image

Releases - Is Latest? GraphQL vs REST

REST GraphQL
Image Image

Events

Where is the "Repo settings" changed event?
Where is the "Organizations settings" changes event?

Limits

Secret and variable names can only contain alphanumeric characters ([a-z], [A-Z], [0-9]) or underscores (_). Spaces are not allowed. Must start with a letter ([a-z], [A-Z]) or underscores (_).

Items Organization Repository Environment
Secrets 1000 100 100
Variables 1000 500 (says limit is 100) 100
Environments - > 10.000 -
Error for repo variable (mistakenly says 100)

Image

Get-GitHubVariable -Owner psmodule-test-org -Repository test | Measure-Object

Count             : 500
Average           : 
Sum               : 
Maximum           : 
Minimum           : 
StandardDeviation : 
Property          : 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions