Compare commits

...

67 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 4869139f44 Address code review feedback
- Remove awkward blank lines left after removing eslint-disable comments
- Add baseUrl to tsconfig.json for proper paths resolution

Co-authored-by: henrymercer <14129055+henrymercer@users.noreply.github.com>
2026-01-28 18:51:48 +00:00
copilot-swe-agent[bot] 712b51a568 Also disable no-unsafe-argument rule
This rule is also triggered by stricter types in @actions/github v9

Co-authored-by: henrymercer <14129055+henrymercer@users.noreply.github.com>
2026-01-28 18:46:47 +00:00
copilot-swe-agent[bot] 0d61442a70 Fix ESLint errors caused by @actions/github v9 upgrade
- Add @actions/github to ESLint import/ignore list to avoid parse errors
- Disable @typescript-eslint/no-unsafe-call and no-unsafe-return rules
- Add TypeScript paths mapping for @octokit/core/types
- Remove unused eslint-disable directives

Co-authored-by: henrymercer <14129055+henrymercer@users.noreply.github.com>
2026-01-28 18:45:04 +00:00
copilot-swe-agent[bot] c4b6a67406 Initial plan 2026-01-28 18:38:23 +00:00
dependabot[bot] 90b2d28dad Bump @actions/github from 8.0.0 to 9.0.0
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 8.0.0 to 9.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

---
updated-dependencies:
- dependency-name: "@actions/github"
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-28 17:53:43 +00:00
Michael B. Gale 1314d3d17e Merge pull request #3439 from github/mbg/fix-proxy-test
Remove `gh` setup from global proxy test
2026-01-28 13:58:28 +00:00
Michael B. Gale f7f9d3f341 Remove gh setup from global proxy test 2026-01-28 13:35:59 +00:00
Henry Mercer eb5bd2d0b9 Merge pull request #3421 from github/henrymercer/only-request-properties-for-orgs
Tolerate errors loading repository properties
2026-01-28 04:00:31 -08:00
Henry Mercer 9aa0515f67 Update comments 2026-01-28 11:33:06 +00:00
Henry Mercer 0720e13f0b Log repository owner type explicitly 2026-01-28 11:30:35 +00:00
Henry Mercer 38ba96d2aa Merge branch 'main' into henrymercer/only-request-properties-for-orgs 2026-01-27 18:28:33 +00:00
Henry Mercer 679da45cc3 Add basic unit tests for Result class 2026-01-27 15:19:17 +00:00
Henry Mercer d5dd165f8b Ensure default value is assignable if we have a Failure 2026-01-27 15:18:50 +00:00
Henry Mercer fbf75ebd7b Merge branch 'main' into henrymercer/only-request-properties-for-orgs 2026-01-27 15:17:20 +00:00
Henry Mercer 6a50972d16 Introduce addNoLanguageDiagnostic 2026-01-27 15:14:32 +00:00
Henry Mercer 5cb12c41c2 Include "Result" in name 2026-01-27 15:11:48 +00:00
Henry Mercer e8f487178f Add some doc for loadRepositoryProperties 2026-01-27 15:11:01 +00:00
Henry Mercer a0671be58e Add doc for Result 2026-01-27 15:07:46 +00:00
Henry Mercer 9ea34c5169 Result: Make use of type hint 2026-01-27 15:05:03 +00:00
Henry Mercer 9fda641d8d Prefer accessing context via @actions/github 2026-01-27 15:00:52 +00:00
Henry Mercer b126facd4e Merge pull request #3434 from github/mbg/dependabot/cooldown
Add `cooldown` settings for Dependabot
2026-01-27 06:57:30 -08:00
Henry Mercer 835dadecbf Merge pull request #3420 from github/henrymercer/compute-job-status-if-no-config
Simplify computation of job status
2026-01-27 06:51:55 -08:00
Henry Mercer a02edfe319 Merge pull request #3424 from github/henrymercer/feature-skip-file-coverage-info-prs
Add feature flag to skip computing baseline file coverage information on PRs
2026-01-27 06:49:29 -08:00
Michael B. Gale 173919c9d5 Merge pull request #3436 from github/mbg/rebuild-js-es2022
Update JS for ES2022
2026-01-27 14:46:54 +00:00
Henry Mercer 6095dc4d51 Merge branch 'main' into henrymercer/compute-job-status-if-no-config 2026-01-27 14:31:51 +00:00
Henry Mercer b333fc6f5b Split up getFinalJobStatus 2026-01-27 14:30:42 +00:00
Henry Mercer 60b658ed10 Update comment 2026-01-27 14:26:31 +00:00
Michael B. Gale e4e324705e Update JS 2026-01-27 14:13:28 +00:00
github-actions[bot] faf7a50b01 Rebuild 2026-01-27 14:13:05 +00:00
Michael B. Gale 2591c2031f Add cooldown settings for Dependabot 2026-01-27 14:08:27 +00:00
Michael B. Gale 34cae51104 Merge pull request #3422 from github/mbg/start-proxy/warn-if-pat-without-username
Warn if a private registry configuration uses a PAT, but has no username
2026-01-27 14:07:06 +00:00
Henry Mercer 9308bcd6bb Add unit tests for file coverage enablement 2026-01-27 13:55:22 +00:00
Michael B. Gale fa9b76ac37 Merge pull request #3432 from github/dependabot/npm_and_yarn/actions/github-8.0.0
Bump @actions/github from 7.0.0 to 8.0.0
2026-01-27 13:49:13 +00:00
Michael B. Gale 6059a66dec Remove @octokit/plugin-retry from Dependabot ignore list 2026-01-27 13:22:57 +00:00
Michael B. Gale cb4fc9e8db Update @octokit/plugin-retry 2026-01-27 13:10:33 +00:00
Michael B. Gale be82188a2a Bump ES version, required by newer @octokit/request-error 2026-01-27 13:09:39 +00:00
Michael B. Gale c656a11252 Use .match in isAuthToken and add repeated call to test 2026-01-27 11:45:03 +00:00
Michael B. Gale bd9f639752 Merge pull request #3433 from github/dependabot/github_actions/dot-github/workflows/actions-minor-69d791f5c9
Bump ruby/setup-ruby from 1.284.0 to 1.286.0 in /.github/workflows in the actions-minor group across 1 directory
2026-01-27 11:31:46 +00:00
Michael B. Gale 0a0c3a2e09 Merge branch 'main' into mbg/start-proxy/warn-if-pat-without-username 2026-01-27 11:27:31 +00:00
github-actions[bot] 46a8de52fc Rebuild 2026-01-26 19:47:52 +00:00
dependabot[bot] f8cea24201 Bump ruby/setup-ruby
Bumps the actions-minor group with 1 update in the /.github/workflows directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby).


Updates `ruby/setup-ruby` from 1.284.0 to 1.286.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](https://github.com/ruby/setup-ruby/compare/80740b3b13bf9857e28854481ca95a84e78a2bdf...90be1154f987f4dc0fe0dd0feedac9e473aa4ba8)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.286.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-26 19:46:17 +00:00
dependabot[bot] b1993d9139 Bump @actions/github from 7.0.0 to 8.0.0
Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 7.0.0 to 8.0.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

---
updated-dependencies:
- dependency-name: "@actions/github"
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-26 19:40:04 +00:00
Henry Mercer ee1e1399e2 Merge pull request #3429 from github/mergeback/v4.32.0-to-main-b20883b0
Mergeback v4.32.0 refs/heads/releases/v4 into main
2026-01-26 11:18:48 -08:00
github-actions[bot] e7d3af2e1e Rebuild 2026-01-26 18:54:35 +00:00
github-actions[bot] 13a6d8be95 Update changelog and version after v4.32.0 2026-01-26 18:39:39 +00:00
Henry Mercer bf20b3e07b Exclude PR check from feature flag 2026-01-26 18:04:37 +00:00
Henry Mercer f1aa4f497a Explain why we ignore extra baseline files options 2026-01-26 18:02:58 +00:00
Henry Mercer 9a55d5bc5f Improve log message 2026-01-26 18:00:34 +00:00
Henry Mercer 17cd475099 Move to separate function 2026-01-26 17:55:17 +00:00
Henry Mercer 18c2cfc765 Indulge caniuse-lite to avoid build warnings 2026-01-26 11:42:13 +00:00
Henry Mercer 1996ca9f5d Log when file coverage info is disabled 2026-01-26 11:42:13 +00:00
Henry Mercer 12c4c7d0e9 Don't log empty summaries 2026-01-26 11:42:13 +00:00
Henry Mercer 919e8aaa40 Mention caveat in feature JSDoc 2026-01-26 11:00:04 +00:00
Henry Mercer 4918026b93 Use FF to disable baseline file coverage 2026-01-26 11:00:04 +00:00
Henry Mercer e8c164b902 Remove unused database print-baseline 2026-01-26 11:00:03 +00:00
Michael B. Gale 9fccf271ff Warn if a private registry configuration uses a PAT, but has no username 2026-01-24 13:02:41 +00:00
Michael B. Gale c12cf8d49a Move makeTestToken to testing-utils 2026-01-24 12:55:32 +00:00
Michael B. Gale 0fcbec3eec Add isAuthToken function, with tests 2026-01-24 12:38:14 +00:00
Michael B. Gale 0ae8b05d08 Extend unit tests to cover all token types 2026-01-24 12:25:40 +00:00
Michael B. Gale 49cdf744d9 Use enum for token types 2026-01-24 11:58:10 +00:00
Michael B. Gale aac4202424 Add fine-grained tokens to GITHUB_TOKEN_PATTERNS 2026-01-24 11:52:53 +00:00
Henry Mercer e7ece62b96 Add feature flag to skip file coverage information on PRs 2026-01-23 18:41:24 +00:00
Henry Mercer d9e374ef85 Tolerate failures loading repository properties 2026-01-23 17:51:41 +00:00
Henry Mercer f4b47e7013 Add result type 2026-01-23 17:51:02 +00:00
Henry Mercer 4e14537b54 Improve logging when no known repository properties found 2026-01-23 17:29:15 +00:00
Henry Mercer e142eee9b4 Only load repository properties for repos owned by orgs 2026-01-23 17:20:30 +00:00
Henry Mercer dcd1b12beb Simplify computation of job status
- Move it out of the failed SARIF reporting so we compute the job status
whether or not we have a CodeQL config.
- Add comments to clarify what happens in the case that the CodeQL
config is absent.
2026-01-23 17:07:21 +00:00
49 changed files with 311888 additions and 81041 deletions
+9 -4
View File
@@ -4,14 +4,15 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: weekly interval: weekly
cooldown:
default-days: 7
exclude:
- "@actions/*"
labels: labels:
- Rebuild - Rebuild
# Ignore incompatible dependency updates # Ignore incompatible dependency updates
ignore: ignore:
# There is a type incompatibility issue between v0.0.9 and our other dependencies. # This is broken due to the way configuration files have changed.
- dependency-name: "@octokit/plugin-retry"
versions: ["~6.0.0"]
# This is broken due to the way configuration files have changed.
# This might be fixed when we move to eslint v9. # This might be fixed when we move to eslint v9.
- dependency-name: "eslint-plugin-import" - dependency-name: "eslint-plugin-import"
versions: [">=2.30.0"] versions: [">=2.30.0"]
@@ -28,6 +29,10 @@ updates:
- "/.github/actions" - "/.github/actions"
schedule: schedule:
interval: weekly interval: weekly
cooldown:
default-days: 7
exclude:
- "actions/*"
labels: labels:
- Rebuild - Rebuild
groups: groups:
@@ -125,5 +125,6 @@ jobs:
fi fi
done done
env: env:
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
CODEQL_ACTION_TEST_MODE: true CODEQL_ACTION_TEST_MODE: true
-12
View File
@@ -48,18 +48,6 @@ jobs:
timeout-minutes: 45 timeout-minutes: 45
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
# These steps are required to initialise the `gh` cli in a container that doesn't
# come pre-installed with it. The reason for that is that this is later
# needed by the `prepare-test` workflow to find the latest release of CodeQL.
- name: Set up GitHub CLI
run: |
apt update
apt install -y curl libreadline8 gnupg2 software-properties-common zstd
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
apt-key add /usr/share/keyrings/githubcli-archive-keyring.gpg
apt-add-repository https://cli.github.com/packages
apt install -y gh
env: {}
- name: Check out repository - name: Check out repository
uses: actions/checkout@v6 uses: actions/checkout@v6
- name: Prepare test - name: Prepare test
+1 -1
View File
@@ -56,7 +56,7 @@ jobs:
use-all-platform-bundle: 'false' use-all-platform-bundle: 'false'
setup-kotlin: 'true' setup-kotlin: 'true'
- name: Set up Ruby - name: Set up Ruby
uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf # v1.284.0 uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with: with:
ruby-version: 2.6 ruby-version: 2.6
- name: Install Code Scanning integration - name: Install Code Scanning integration
+4
View File
@@ -2,6 +2,10 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## [UNRELEASED]
No user facing changes.
## 4.32.0 - 26 Jan 2026 ## 4.32.0 - 26 Jan 2026
- Update default CodeQL bundle version to [2.24.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0). [#3425](https://github.com/github/codeql-action/pull/3425) - Update default CodeQL bundle version to [2.24.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0). [#3425](https://github.com/github/codeql-action/pull/3425)
+4 -1
View File
@@ -78,7 +78,7 @@ export default [
typescript: {}, typescript: {},
}, },
"import/ignore": ["sinon", "uuid", "@octokit/plugin-retry", "del", "get-folder-size"], "import/ignore": ["sinon", "uuid", "@octokit/plugin-retry", "del", "get-folder-size", "@actions/github"],
}, },
rules: { rules: {
@@ -152,9 +152,12 @@ export default [
rules: { rules: {
"@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-assignment": "off", "@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-enum-comparison": "off", "@typescript-eslint/no-unsafe-enum-comparison": "off",
"@typescript-eslint/no-unsafe-member-access": "off", "@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-var-requires": "off", "@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/prefer-regexp-exec": "off", "@typescript-eslint/prefer-regexp-exec": "off",
"@typescript-eslint/require-await": "off", "@typescript-eslint/require-await": "off",
+28732 -7004
View File
File diff suppressed because one or more lines are too long
+24426 -6504
View File
File diff suppressed because one or more lines are too long
+24409 -6493
View File
File diff suppressed because one or more lines are too long
+29218 -7478
View File
File diff suppressed because one or more lines are too long
+24646 -6641
View File
File diff suppressed because one or more lines are too long
+24404 -6493
View File
File diff suppressed because one or more lines are too long
+24409 -6493
View File
File diff suppressed because one or more lines are too long
+28721 -6992
View File
File diff suppressed because one or more lines are too long
+24449 -6483
View File
File diff suppressed because one or more lines are too long
+24403 -6493
View File
File diff suppressed because one or more lines are too long
+28721 -6992
View File
File diff suppressed because one or more lines are too long
+24411 -6496
View File
File diff suppressed because one or more lines are too long
+260 -266
View File
@@ -1,12 +1,12 @@
{ {
"name": "codeql", "name": "codeql",
"version": "4.32.0", "version": "4.32.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "codeql", "name": "codeql",
"version": "4.32.0", "version": "4.32.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "^5.0.2", "@actions/artifact": "^5.0.2",
@@ -14,12 +14,12 @@
"@actions/cache": "^5.0.3", "@actions/cache": "^5.0.3",
"@actions/core": "^2.0.2", "@actions/core": "^2.0.2",
"@actions/exec": "^2.0.0", "@actions/exec": "^2.0.0",
"@actions/github": "^7.0.0", "@actions/github": "^9.0.0",
"@actions/glob": "^0.5.0", "@actions/glob": "^0.5.0",
"@actions/http-client": "^3.0.0", "@actions/http-client": "^3.0.0",
"@actions/io": "^2.0.0", "@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.0", "@actions/tool-cache": "^3.0.0",
"@octokit/plugin-retry": "^6.0.0", "@octokit/plugin-retry": "^8.0.0",
"@schemastore/package": "0.0.10", "@schemastore/package": "0.0.10",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@@ -164,6 +164,33 @@
"undici": "^5.25.4" "undici": "^5.25.4"
} }
}, },
"node_modules/@actions/artifact/node_modules/@octokit/auth-token": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
"license": "MIT",
"engines": {
"node": ">= 18"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/core": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz",
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.1.0",
"@octokit/request": "^8.4.1",
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.0.0",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/endpoint": { "node_modules/@actions/artifact/node_modules/@octokit/endpoint": {
"version": "9.0.6", "version": "9.0.6",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
@@ -177,12 +204,86 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/@actions/artifact/node_modules/@octokit/graphql": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz",
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^8.4.1",
"@octokit/types": "^13.0.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/openapi-types": { "node_modules/@actions/artifact/node_modules/@octokit/openapi-types": {
"version": "12.11.0", "version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@actions/artifact/node_modules/@octokit/plugin-paginate-rest": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/plugin-retry": { "node_modules/@actions/artifact/node_modules/@octokit/plugin-retry": {
"version": "3.0.9", "version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
@@ -243,6 +344,12 @@
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==" "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="
}, },
"node_modules/@actions/artifact/node_modules/before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
"license": "Apache-2.0"
},
"node_modules/@actions/cache": { "node_modules/@actions/cache": {
"version": "5.0.3", "version": "5.0.3",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.3.tgz", "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-5.0.3.tgz",
@@ -288,77 +395,69 @@
} }
}, },
"node_modules/@actions/github": { "node_modules/@actions/github": {
"version": "7.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-7.0.0.tgz", "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.0.0.tgz",
"integrity": "sha512-PyGODO938aoBTZd/IfN/+e+Pd5hUcVpyf+thm4CPESLeqhdSkq5QwMTGX9v84XHE1ifmHWBQ60KB8kIgm96opw==", "integrity": "sha512-yJ0RoswsAaKcvkmpCE4XxBRiy/whH2SdTBHWzs0gi4wkqTDhXMChjSdqBz/F4AeiDlP28rQqL33iHb+kjAMX6w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/http-client": "^3.0.1", "@actions/http-client": "^3.0.2",
"@octokit/core": "^5.0.1", "@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": "^9.2.2", "@octokit/plugin-paginate-rest": "^14.0.0",
"@octokit/plugin-rest-endpoint-methods": "^10.4.0", "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"@octokit/request": "^8.4.1", "@octokit/request": "^10.0.7",
"@octokit/request-error": "^5.1.1", "@octokit/request-error": "^7.1.0",
"undici": "^5.28.5" "undici": "^6.23.0"
} }
}, },
"node_modules/@actions/github/node_modules/@octokit/endpoint": { "node_modules/@actions/github/node_modules/@actions/http-client": {
"version": "9.0.6", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz",
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^13.1.0", "tunnel": "^0.0.6",
"universal-user-agent": "^6.0.0" "undici": "^6.23.0"
}
},
"node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
} }
}, },
"node_modules/@actions/github/node_modules/@octokit/request": { "node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "8.4.1", "version": "17.0.0",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz",
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@octokit/endpoint": "^9.0.6", "@octokit/types": "^16.0.0"
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/@octokit/request-error": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.1.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}, },
"engines": { "peerDependencies": {
"node": ">= 18" "@octokit/core": ">=6"
} }
}, },
"node_modules/@actions/github/node_modules/@octokit/types": { "node_modules/@actions/github/node_modules/undici": {
"version": "13.10.0", "version": "6.23.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
"license": "MIT", "license": "MIT",
"dependencies": { "engines": {
"@octokit/openapi-types": "^24.2.0" "node": ">=18.17"
} }
}, },
"node_modules/@actions/github/node_modules/@octokit/types/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
"license": "MIT"
},
"node_modules/@actions/glob": { "node_modules/@actions/glob": {
"version": "0.5.0", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.5.0.tgz", "resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.5.0.tgz",
@@ -1649,185 +1748,83 @@
} }
}, },
"node_modules/@octokit/auth-token": { "node_modules/@octokit/auth-token": {
"version": "4.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz",
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==",
"license": "MIT",
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
} }
}, },
"node_modules/@octokit/core": { "node_modules/@octokit/core": {
"version": "5.2.2", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz",
"integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@octokit/auth-token": "^4.0.0", "@octokit/auth-token": "^6.0.0",
"@octokit/graphql": "^7.1.0", "@octokit/graphql": "^9.0.3",
"@octokit/request": "^8.4.1", "@octokit/request": "^10.0.6",
"@octokit/request-error": "^5.1.1", "@octokit/request-error": "^7.0.2",
"@octokit/types": "^13.0.0", "@octokit/types": "^16.0.0",
"before-after-hook": "^2.2.0", "before-after-hook": "^4.0.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^7.0.0"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
} }
}, },
"node_modules/@octokit/core/node_modules/@octokit/endpoint": { "node_modules/@octokit/core/node_modules/universal-user-agent": {
"version": "9.0.6", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
"license": "ISC"
},
"node_modules/@octokit/endpoint": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz",
"integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^13.1.0", "@octokit/types": "^16.0.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^7.0.2"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
} }
}, },
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": { "node_modules/@octokit/endpoint/node_modules/universal-user-agent": {
"version": "24.2.0", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==" "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
}, "license": "ISC"
"node_modules/@octokit/core/node_modules/@octokit/request": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
"dependencies": {
"@octokit/endpoint": "^9.0.6",
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core/node_modules/@octokit/request-error": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
"dependencies": {
"@octokit/types": "^13.1.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core/node_modules/@octokit/types": {
"version": "13.10.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
}, },
"node_modules/@octokit/graphql": { "node_modules/@octokit/graphql": {
"version": "7.1.1", "version": "9.0.3",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz",
"integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/request": "^8.4.1", "@octokit/request": "^10.0.6",
"@octokit/types": "^13.0.0", "@octokit/types": "^16.0.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^7.0.0"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
} }
}, },
"node_modules/@octokit/graphql/node_modules/@octokit/endpoint": { "node_modules/@octokit/graphql/node_modules/universal-user-agent": {
"version": "9.0.6", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
"dependencies": { "license": "ISC"
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="
},
"node_modules/@octokit/graphql/node_modules/@octokit/request": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
"integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
"dependencies": {
"@octokit/endpoint": "^9.0.6",
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/request-error": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
"dependencies": {
"@octokit/types": "^13.1.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
"version": "13.10.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
}, },
"node_modules/@octokit/openapi-types": { "node_modules/@octokit/openapi-types": {
"version": "27.0.0", "version": "27.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
"integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@octokit/plugin-paginate-rest": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
"integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@octokit/plugin-request-log": { "node_modules/@octokit/plugin-request-log": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
@@ -1837,83 +1834,61 @@
"@octokit/core": ">=3" "@octokit/core": ">=3"
} }
}, },
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@octokit/plugin-retry": { "node_modules/@octokit/plugin-retry": {
"version": "6.1.0", "version": "8.0.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.0.3.tgz",
"integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==", "integrity": "sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/request-error": "^5.0.0", "@octokit/request-error": "^7.0.2",
"@octokit/types": "^13.0.0", "@octokit/types": "^16.0.0",
"bottleneck": "^2.15.3" "bottleneck": "^2.15.3"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
}, },
"peerDependencies": { "peerDependencies": {
"@octokit/core": "5" "@octokit/core": ">=7"
} }
}, },
"node_modules/@octokit/plugin-retry/node_modules/@octokit/openapi-types": { "node_modules/@octokit/request": {
"version": "24.2.0", "version": "10.0.7",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz",
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==" "integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==",
}, "license": "MIT",
"node_modules/@octokit/plugin-retry/node_modules/@octokit/request-error": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
"integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
"dependencies": { "dependencies": {
"@octokit/types": "^13.1.0", "@octokit/endpoint": "^11.0.2",
"deprecation": "^2.0.0", "@octokit/request-error": "^7.0.2",
"once": "^1.4.0" "@octokit/types": "^16.0.0",
"fast-content-type-parse": "^3.0.0",
"universal-user-agent": "^7.0.2"
}, },
"engines": { "engines": {
"node": ">= 18" "node": ">= 20"
} }
}, },
"node_modules/@octokit/plugin-retry/node_modules/@octokit/types": { "node_modules/@octokit/request-error": {
"version": "13.10.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/openapi-types": "^24.2.0" "@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
} }
}, },
"node_modules/@octokit/request/node_modules/universal-user-agent": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
"license": "ISC"
},
"node_modules/@octokit/types": { "node_modules/@octokit/types": {
"version": "16.0.0", "version": "16.0.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
"integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@octokit/openapi-types": "^27.0.0" "@octokit/openapi-types": "^27.0.0"
@@ -3663,7 +3638,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/before-after-hook": { "node_modules/before-after-hook": {
"version": "2.2.3", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz",
"integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==",
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/binary": { "node_modules/binary": {
@@ -3834,9 +3811,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001727", "version": "1.0.30001766",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz",
"integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -3851,7 +3828,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/cbor": { "node_modules/cbor": {
"version": "10.0.9", "version": "10.0.9",
@@ -5450,6 +5428,22 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1" "url": "https://github.com/sindresorhus/execa?sponsor=1"
} }
}, },
"node_modules/fast-content-type-parse": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
"integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/fast-deep-equal": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"license": "MIT" "license": "MIT"
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "codeql", "name": "codeql",
"version": "4.32.0", "version": "4.32.1",
"private": true, "private": true,
"description": "CodeQL action", "description": "CodeQL action",
"scripts": { "scripts": {
@@ -29,12 +29,12 @@
"@actions/cache": "^5.0.3", "@actions/cache": "^5.0.3",
"@actions/core": "^2.0.2", "@actions/core": "^2.0.2",
"@actions/exec": "^2.0.0", "@actions/exec": "^2.0.0",
"@actions/github": "^7.0.0", "@actions/github": "^9.0.0",
"@actions/glob": "^0.5.0", "@actions/glob": "^0.5.0",
"@actions/http-client": "^3.0.0", "@actions/http-client": "^3.0.0",
"@actions/io": "^2.0.0", "@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.0", "@actions/tool-cache": "^3.0.0",
"@octokit/plugin-retry": "^6.0.0", "@octokit/plugin-retry": "^8.0.0",
"@schemastore/package": "0.0.10", "@schemastore/package": "0.0.10",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
@@ -5,6 +5,7 @@ versions: ["nightly-latest"]
installGo: true installGo: true
installDotNet: true installDotNet: true
env: env:
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
steps: steps:
- uses: ./../action/init - uses: ./../action/init
-13
View File
@@ -3,19 +3,6 @@ description: "Tests using a proxy specified by the https_proxy environment varia
versions: ["linked", "nightly-latest"] versions: ["linked", "nightly-latest"]
container: container:
image: ubuntu:22.04 image: ubuntu:22.04
container-init-steps:
# These steps are required to initialise the `gh` cli in a container that doesn't
# come pre-installed with it. The reason for that is that this is later
# needed by the `prepare-test` workflow to find the latest release of CodeQL.
name: Set up GitHub CLI
run: |
apt update
apt install -y curl libreadline8 gnupg2 software-properties-common zstd
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
apt-key add /usr/share/keyrings/githubcli-archive-keyring.gpg
apt-add-repository https://cli.github.com/packages
apt install -y gh
env: {}
services: services:
squid-proxy: squid-proxy:
image: ubuntu/squid:latest image: ubuntu/squid:latest
+1 -1
View File
@@ -4,7 +4,7 @@ description: "Tests using RuboCop to analyze a multi-language repository and the
versions: ["default"] versions: ["default"]
steps: steps:
- name: Set up Ruby - name: Set up Ruby
uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf # v1.284.0 uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with: with:
ruby-version: 2.6 ruby-version: 2.6
- name: Install Code Scanning integration - name: Install Code Scanning integration
-1
View File
@@ -87,7 +87,6 @@ test("status report fields", async (t) => {
); );
return ""; return "";
}, },
databasePrintBaseline: async () => "",
}); });
const config = createTestConfig({ const config = createTestConfig({
+10 -2
View File
@@ -495,10 +495,18 @@ export async function runQueries(
endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime();
logger.endGroup(); logger.endGroup();
logger.info(analysisSummary); if (analysisSummary.trim()) {
if (qualityAnalysisSummary) { logger.info(analysisSummary);
}
if (qualityAnalysisSummary?.trim()) {
logger.info(qualityAnalysisSummary); logger.info(qualityAnalysisSummary);
} }
if (!config.enableFileCoverageInformation) {
logger.info(
"To speed up pull request analysis, file coverage information is only enabled when analyzing " +
"the default branch and protected branches.",
);
}
if (await features.getValue(Feature.QaTelemetryEnabled)) { if (await features.getValue(Feature.QaTelemetryEnabled)) {
// Note: QA adds the `code-quality` query suite to the `queries` input, // Note: QA adds the `code-quality` query suite to the `queries` input,
-1
View File
@@ -52,7 +52,6 @@ function mockGetMetaVersionHeader(
}; };
const spyGetContents = sinon const spyGetContents = sinon
.stub(client.rest.meta, "get") .stub(client.rest.meta, "get")
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
.resolves(response as any); .resolves(response as any);
sinon.stub(api, "getApiClient").value(() => client); sinon.stub(api, "getApiClient").value(() => client);
return spyGetContents; return spyGetContents;
-1
View File
@@ -116,7 +116,6 @@ export async function getGitHubVersionFromApi(
// Doesn't strictly have to be the meta endpoint as we're only // Doesn't strictly have to be the meta endpoint as we're only
// using the response headers which are available on every request. // using the response headers which are available on every request.
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const response = await apiClient.rest.meta.get(); const response = await apiClient.rest.meta.get();
// This happens on dotcom, although we expect to have already returned in that // This happens on dotcom, although we expect to have already returned in that
+112 -27
View File
@@ -4,37 +4,122 @@ import * as path from "path";
import test from "ava"; import test from "ava";
import { scanArtifactsForTokens } from "./artifact-scanner"; import {
GITHUB_PAT_CLASSIC_PATTERN,
isAuthToken,
scanArtifactsForTokens,
TokenType,
} from "./artifact-scanner";
import { getRunnerLogger } from "./logging"; import { getRunnerLogger } from "./logging";
import { getRecordingLogger, LoggedMessage } from "./testing-utils"; import {
checkExpectedLogMessages,
getRecordingLogger,
LoggedMessage,
makeTestToken,
} from "./testing-utils";
test("scanArtifactsForTokens detects GitHub tokens in files", async (t) => { test("makeTestToken", (t) => {
const logger = getRunnerLogger(true); t.is(makeTestToken().length, 36);
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-")); t.is(makeTestToken(255).length, 255);
try {
// Create a test file with a fake GitHub token
const testFile = path.join(tempDir, "test.txt");
fs.writeFileSync(
testFile,
"This is a test file with token ghp_1234567890123456789012345678901234AB",
);
const error = await t.throwsAsync(
async () => await scanArtifactsForTokens([testFile], logger),
);
t.regex(
error?.message || "",
/Found 1 potential GitHub token.*Personal Access Token/,
);
t.regex(error?.message || "", /test\.txt/);
} finally {
// Clean up
fs.rmSync(tempDir, { recursive: true, force: true });
}
}); });
test("isAuthToken", (t) => {
// Undefined for strings that aren't tokens
t.is(isAuthToken("some string"), undefined);
t.is(isAuthToken("ghp_"), undefined);
t.is(isAuthToken("ghp_123"), undefined);
// Token types for strings that are tokens.
t.is(isAuthToken(`ghp_${makeTestToken()}`), TokenType.PersonalAccessClassic);
t.is(isAuthToken(`ghp_${makeTestToken()}`), TokenType.PersonalAccessClassic);
t.is(
isAuthToken(`ghs_${makeTestToken(255)}`),
TokenType.AppInstallationAccess,
);
t.is(
isAuthToken(`github_pat_${makeTestToken(22)}_${makeTestToken(59)}`),
TokenType.PersonalAccessFineGrained,
);
// With a custom pattern set
t.is(
isAuthToken(`ghp_${makeTestToken()}`, [GITHUB_PAT_CLASSIC_PATTERN]),
TokenType.PersonalAccessClassic,
);
t.is(
isAuthToken(`github_pat_${makeTestToken(22)}_${makeTestToken(59)}`, [
GITHUB_PAT_CLASSIC_PATTERN,
]),
undefined,
);
});
const testTokens = [
{
type: TokenType.PersonalAccessClassic,
value: `ghp_${makeTestToken()}`,
checkPattern: "Personal Access Token",
},
{
type: TokenType.PersonalAccessFineGrained,
value:
"github_pat_1234567890ABCDEFGHIJKL_MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHI",
checkPattern: "Personal Access Token",
},
{
type: TokenType.OAuth,
value: `gho_${makeTestToken()}`,
},
{
type: TokenType.UserToServer,
value: `ghu_${makeTestToken()}`,
},
{
type: TokenType.ServerToServer,
value: `ghs_${makeTestToken()}`,
},
{
type: TokenType.Refresh,
value: `ghr_${makeTestToken()}`,
},
{
type: TokenType.AppInstallationAccess,
value: `ghs_${makeTestToken(255)}`,
},
];
for (const { type, value, checkPattern } of testTokens) {
test(`scanArtifactsForTokens detects GitHub ${type} tokens in files`, async (t) => {
const logMessages = [];
const logger = getRecordingLogger(logMessages, { logToConsole: false });
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-"));
try {
// Create a test file with a fake GitHub token
const testFile = path.join(tempDir, "test.txt");
fs.writeFileSync(testFile, `This is a test file with token ${value}`);
const error = await t.throwsAsync(
async () => await scanArtifactsForTokens([testFile], logger),
);
t.regex(
error?.message || "",
new RegExp(`Found 1 potential GitHub token.*${checkPattern || type}`),
);
t.regex(error?.message || "", /test\.txt/);
checkExpectedLogMessages(t, logMessages, [
"Starting best-effort check",
`Found 1 ${type}`,
]);
} finally {
// Clean up
fs.rmSync(tempDir, { recursive: true, force: true });
}
});
}
test("scanArtifactsForTokens handles files without tokens", async (t) => { test("scanArtifactsForTokens handles files without tokens", async (t) => {
const logger = getRunnerLogger(true); const logger = getRunnerLogger(true);
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-")); const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-"));
+60 -13
View File
@@ -7,33 +7,62 @@ import * as exec from "@actions/exec";
import { Logger } from "./logging"; import { Logger } from "./logging";
import { getErrorMessage } from "./util"; import { getErrorMessage } from "./util";
/**
* Enumerates known types of GitHub token formats.
*/
export enum TokenType {
PersonalAccessClassic = "Personal Access Token (Classic)",
PersonalAccessFineGrained = "Personal Access Token (Fine-grained)",
OAuth = "OAuth Access Token",
UserToServer = "User-to-Server Token",
ServerToServer = "Server-to-Server Token",
Refresh = "Refresh Token",
AppInstallationAccess = "App Installation Access Token",
}
/** A value of this type associates a token type with its pattern. */
export interface TokenPattern {
type: TokenType;
pattern: RegExp;
}
/** The pattern for PATs (Classic) */
export const GITHUB_PAT_CLASSIC_PATTERN: TokenPattern = {
type: TokenType.PersonalAccessClassic,
pattern: /\bghp_[a-zA-Z0-9]{36}\b/g,
};
/** The pattern for PATs (Fine-grained) */
export const GITHUB_PAT_FINE_GRAINED_PATTERN: TokenPattern = {
type: TokenType.PersonalAccessFineGrained,
pattern: /\bgithub_pat_[a-zA-Z0-9_]+\b/g,
};
/** /**
* GitHub token patterns to scan for. * GitHub token patterns to scan for.
* These patterns match various GitHub token formats. * These patterns match various GitHub token formats.
*/ */
const GITHUB_TOKEN_PATTERNS = [ const GITHUB_TOKEN_PATTERNS: TokenPattern[] = [
GITHUB_PAT_CLASSIC_PATTERN,
GITHUB_PAT_FINE_GRAINED_PATTERN,
{ {
name: "Personal Access Token", type: TokenType.OAuth,
pattern: /\bghp_[a-zA-Z0-9]{36}\b/g,
},
{
name: "OAuth Access Token",
pattern: /\bgho_[a-zA-Z0-9]{36}\b/g, pattern: /\bgho_[a-zA-Z0-9]{36}\b/g,
}, },
{ {
name: "User-to-Server Token", type: TokenType.UserToServer,
pattern: /\bghu_[a-zA-Z0-9]{36}\b/g, pattern: /\bghu_[a-zA-Z0-9]{36}\b/g,
}, },
{ {
name: "Server-to-Server Token", type: TokenType.ServerToServer,
pattern: /\bghs_[a-zA-Z0-9]{36}\b/g, pattern: /\bghs_[a-zA-Z0-9]{36}\b/g,
}, },
{ {
name: "Refresh Token", type: TokenType.Refresh,
pattern: /\bghr_[a-zA-Z0-9]{36}\b/g, pattern: /\bghr_[a-zA-Z0-9]{36}\b/g,
}, },
{ {
name: "App Installation Access Token", type: TokenType.AppInstallationAccess,
pattern: /\bghs_[a-zA-Z0-9]{255}\b/g, pattern: /\bghs_[a-zA-Z0-9]{255}\b/g,
}, },
]; ];
@@ -48,6 +77,24 @@ interface ScanResult {
findings: TokenFinding[]; findings: TokenFinding[];
} }
/**
* Checks whether `value` matches any token `patterns`.
* @param value The value to match against.
* @param patterns The patterns to check.
* @returns The type of the first matching pattern, or `undefined` if none match.
*/
export function isAuthToken(
value: string,
patterns: TokenPattern[] = GITHUB_TOKEN_PATTERNS,
) {
for (const { type, pattern } of patterns) {
if (value.match(pattern)) {
return type;
}
}
return undefined;
}
/** /**
* Scans a file for GitHub tokens. * Scans a file for GitHub tokens.
* *
@@ -65,13 +112,13 @@ function scanFileForTokens(
try { try {
const content = fs.readFileSync(filePath, "utf8"); const content = fs.readFileSync(filePath, "utf8");
for (const { name, pattern } of GITHUB_TOKEN_PATTERNS) { for (const { type, pattern } of GITHUB_TOKEN_PATTERNS) {
const matches = content.match(pattern); const matches = content.match(pattern);
if (matches) { if (matches) {
for (let i = 0; i < matches.length; i++) { for (let i = 0; i < matches.length; i++) {
findings.push({ tokenType: name, filePath: relativePath }); findings.push({ tokenType: type, filePath: relativePath });
} }
logger.debug(`Found ${matches.length} ${name}(s) in ${relativePath}`); logger.debug(`Found ${matches.length} ${type}(s) in ${relativePath}`);
} }
} }
+12 -20
View File
@@ -186,10 +186,6 @@ export interface CodeQL {
config: Config, config: Config,
features: FeatureEnablement, features: FeatureEnablement,
): Promise<string>; ): Promise<string>;
/**
* Run 'codeql database print-baseline'.
*/
databasePrintBaseline(databasePath: string): Promise<string>;
/** /**
* Run 'codeql database export-diagnostics' * Run 'codeql database export-diagnostics'
* *
@@ -493,10 +489,6 @@ export function createStubCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
partialCodeql, partialCodeql,
"databaseInterpretResults", "databaseInterpretResults",
), ),
databasePrintBaseline: resolveFunction(
partialCodeql,
"databasePrintBaseline",
),
databaseExportDiagnostics: resolveFunction( databaseExportDiagnostics: resolveFunction(
partialCodeql, partialCodeql,
"databaseExportDiagnostics", "databaseExportDiagnostics",
@@ -628,6 +620,13 @@ async function getCodeQLForCmd(
extraArgs.push("--overlay-base"); extraArgs.push("--overlay-base");
} }
const baselineFilesOptions = config.enableFileCoverageInformation
? [
"--calculate-language-specific-baseline",
"--sublanguage-file-coverage",
]
: ["--no-calculate-baseline"];
await runCli( await runCli(
cmd, cmd,
[ [
@@ -639,12 +638,14 @@ async function getCodeQLForCmd(
"--db-cluster", "--db-cluster",
config.dbLocation, config.dbLocation,
`--source-root=${sourceRoot}`, `--source-root=${sourceRoot}`,
"--calculate-language-specific-baseline", ...baselineFilesOptions,
"--extractor-include-aliases", "--extractor-include-aliases",
"--sublanguage-file-coverage",
...extraArgs, ...extraArgs,
...getExtraOptionsFromEnv(["database", "init"], { ...getExtraOptionsFromEnv(["database", "init"], {
ignoringOptions: ["--overwrite"], // Some user configs specify `--no-calculate-baseline` as an additional
// argument to `codeql database init`. Therefore ignore the baseline file
// options here to avoid specifying the same argument twice and erroring.
ignoringOptions: ["--overwrite", ...baselineFilesOptions],
}), }),
], ],
{ stdin: externalRepositoryToken }, { stdin: externalRepositoryToken },
@@ -885,15 +886,6 @@ async function getCodeQLForCmd(
noStreamStdout: true, noStreamStdout: true,
}); });
}, },
async databasePrintBaseline(databasePath: string): Promise<string> {
const codeqlArgs = [
"database",
"print-baseline",
...getExtraOptionsFromEnv(["database", "print-baseline"]),
databasePath,
];
return await runCli(cmd, codeqlArgs);
},
async databaseCleanupCluster( async databaseCleanupCluster(
config: Config, config: Config,
cleanupLevel: CleanupLevel, cleanupLevel: CleanupLevel,
+1 -2
View File
@@ -89,6 +89,7 @@ function createTestInitConfigInputs(
}, },
features: createFeatures([]), features: createFeatures([]),
repositoryProperties: {}, repositoryProperties: {},
enableFileCoverageInformation: true,
logger: getRunnerLogger(true), logger: getRunnerLogger(true),
} satisfies configUtils.InitConfigInputs, } satisfies configUtils.InitConfigInputs,
overrides, overrides,
@@ -114,7 +115,6 @@ function mockGetContents(
}; };
const spyGetContents = sinon const spyGetContents = sinon
.stub(client.rest.repos, "getContent") .stub(client.rest.repos, "getContent")
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
.resolves(response as any); .resolves(response as any);
sinon.stub(api, "getApiClient").value(() => client); sinon.stub(api, "getApiClient").value(() => client);
sinon.stub(api, "getApiClientWithExternalAuth").value(() => client); sinon.stub(api, "getApiClientWithExternalAuth").value(() => client);
@@ -130,7 +130,6 @@ function mockListLanguages(languages: string[]) {
for (const language of languages) { for (const language of languages) {
response.data[language] = 123; response.data[language] = 123;
} }
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
sinon.stub(client.rest.repos, "listLanguages").resolves(response as any); sinon.stub(client.rest.repos, "listLanguages").resolves(response as any);
sinon.stub(api, "getApiClient").value(() => client); sinon.stub(api, "getApiClient").value(() => client);
} }
+14 -9
View File
@@ -26,7 +26,10 @@ import {
parseUserConfig, parseUserConfig,
UserConfig, UserConfig,
} from "./config/db-config"; } from "./config/db-config";
import { addDiagnostic, makeTelemetryDiagnostic } from "./diagnostics"; import {
addNoLanguageDiagnostic,
makeTelemetryDiagnostic,
} from "./diagnostics";
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils"; import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment"; import { EnvVar } from "./environment";
import * as errorMessages from "./error-messages"; import * as errorMessages from "./error-messages";
@@ -214,6 +217,11 @@ export interface Config {
* A partial mapping from repository properties that affect us to their values. * A partial mapping from repository properties that affect us to their values.
*/ */
repositoryProperties: RepositoryProperties; repositoryProperties: RepositoryProperties;
/**
* Whether to enable file coverage information.
*/
enableFileCoverageInformation: boolean;
} }
async function getSupportedLanguageMap( async function getSupportedLanguageMap(
@@ -433,6 +441,7 @@ export interface InitConfigInputs {
apiDetails: api.GitHubApiCombinedDetails; apiDetails: api.GitHubApiCombinedDetails;
features: FeatureEnablement; features: FeatureEnablement;
repositoryProperties: RepositoryProperties; repositoryProperties: RepositoryProperties;
enableFileCoverageInformation: boolean;
analysisKinds: AnalysisKind[]; analysisKinds: AnalysisKind[];
logger: Logger; logger: Logger;
} }
@@ -462,6 +471,7 @@ export async function initActionState(
repositoryProperties, repositoryProperties,
analysisKinds, analysisKinds,
logger, logger,
enableFileCoverageInformation,
}: InitConfigInputs, }: InitConfigInputs,
userConfig: UserConfig, userConfig: UserConfig,
): Promise<Config> { ): Promise<Config> {
@@ -542,6 +552,7 @@ export async function initActionState(
overlayDatabaseMode: OverlayDatabaseMode.None, overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false, useOverlayDatabaseCaching: false,
repositoryProperties, repositoryProperties,
enableFileCoverageInformation,
}; };
} }
@@ -1408,11 +1419,8 @@ async function logGitVersionTelemetry(
gitVersion: GitVersionInfo, gitVersion: GitVersionInfo,
): Promise<void> { ): Promise<void> {
if (config.languages.length > 0) { if (config.languages.length > 0) {
addDiagnostic( addNoLanguageDiagnostic(
config, config,
// Arbitrarily choose the first language. We could also choose all languages, but that
// increases the risk of misinterpreting the data.
config.languages[0],
makeTelemetryDiagnostic( makeTelemetryDiagnostic(
"codeql-action/git-version-telemetry", "codeql-action/git-version-telemetry",
"Git version telemetry", "Git version telemetry",
@@ -1438,11 +1446,8 @@ async function logGeneratedFilesTelemetry(
return; return;
} }
addDiagnostic( addNoLanguageDiagnostic(
config, config,
// Arbitrarily choose the first language. We could also choose all languages, but that
// increases the risk of misinterpreting the data.
config.languages[0],
makeTelemetryDiagnostic( makeTelemetryDiagnostic(
"codeql-action/generated-files-telemetry", "codeql-action/generated-files-telemetry",
"Generated files telemetry", "Generated files telemetry",
+14
View File
@@ -117,6 +117,20 @@ export function addDiagnostic(
} }
} }
/** Adds a diagnostic that is not specific to any language. */
export function addNoLanguageDiagnostic(
config: Config,
diagnostic: DiagnosticMessage,
) {
addDiagnostic(
config,
// Arbitrarily choose the first language. We could also choose all languages, but that
// increases the risk of misinterpreting the data.
config.languages[0],
diagnostic,
);
}
/** /**
* Writes the given diagnostic to the database. * Writes the given diagnostic to the database.
* *
+7 -11
View File
@@ -259,17 +259,13 @@ for (const feature of Object.keys(featureConfig)) {
// The type system should prevent this happening, but test that if we // The type system should prevent this happening, but test that if we
// bypass it we get the expected error. // bypass it we get the expected error.
await t.throwsAsync( await t.throwsAsync(async () => features.getValue(feature as any), {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument message: `Internal error: A ${
async () => features.getValue(feature as any), featureConfig[feature].minimumVersion !== undefined
{ ? "minimum version"
message: `Internal error: A ${ : "required tools feature"
featureConfig[feature].minimumVersion !== undefined } is specified for feature ${feature}, but no instance of CodeQL was provided.`,
? "minimum version" });
: "required tools feature"
} is specified for feature ${feature}, but no instance of CodeQL was provided.`,
},
);
}); });
}); });
} }
+11
View File
@@ -70,6 +70,8 @@ export enum Feature {
OverlayAnalysisSwift = "overlay_analysis_swift", OverlayAnalysisSwift = "overlay_analysis_swift",
PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib", PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib",
QaTelemetryEnabled = "qa_telemetry_enabled", QaTelemetryEnabled = "qa_telemetry_enabled",
/** Note that this currently only disables baseline file coverage information. */
SkipFileCoverageOnPrs = "skip_file_coverage_on_prs",
UploadOverlayDbToApi = "upload_overlay_db_to_api", UploadOverlayDbToApi = "upload_overlay_db_to_api",
UseRepositoryProperties = "use_repository_properties", UseRepositoryProperties = "use_repository_properties",
ValidateDbConfig = "validate_db_config", ValidateDbConfig = "validate_db_config",
@@ -286,6 +288,15 @@ export const featureConfig = {
legacyApi: true, legacyApi: true,
minimumVersion: undefined, minimumVersion: undefined,
}, },
[Feature.SkipFileCoverageOnPrs]: {
defaultValue: false,
envVar: "CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS",
// For testing, this is not behind a CLI version check yet. However
// before rolling this out externally, we should set a minimum version here
// since current versions of the CodeQL CLI will log if baseline information
// cannot be found when interpreting results.
minimumVersion: undefined,
},
[Feature.UploadOverlayDbToApi]: { [Feature.UploadOverlayDbToApi]: {
defaultValue: false, defaultValue: false,
envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API", envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API",
+11 -5
View File
@@ -78,11 +78,17 @@ export async function loadPropertiesFromApi(
} }
} }
logger.debug("Loaded the following values for the repository properties:"); if (Object.keys(properties).length === 0) {
for (const [property, value] of Object.entries(properties).sort( logger.debug("No known repository properties were found.");
([nameA], [nameB]) => nameA.localeCompare(nameB), } else {
)) { logger.debug(
logger.debug(` ${property}: ${value}`); "Loaded the following values for the repository properties:",
);
for (const [property, value] of Object.entries(properties).sort(
([nameA], [nameB]) => nameA.localeCompare(nameB),
)) {
logger.debug(` ${property}: ${value}`);
}
} }
return properties; return properties;
+20 -55
View File
@@ -1,6 +1,5 @@
import * as fs from "fs"; import * as fs from "fs";
import * as core from "@actions/core";
import * as github from "@actions/github"; import * as github from "@actions/github";
import * as actionsUtil from "./actions-util"; import * as actionsUtil from "./actions-util";
@@ -129,48 +128,31 @@ export async function tryUploadSarifIfRunFailed(
features: FeatureEnablement, features: FeatureEnablement,
logger: Logger, logger: Logger,
): Promise<UploadFailedSarifResult> { ): Promise<UploadFailedSarifResult> {
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] !== "true") { // Only upload the failed SARIF to Code scanning if Code scanning is enabled.
// If analyze didn't complete successfully and the job status hasn't if (!isCodeScanningEnabled(config)) {
// already been set to Failure/ConfigurationError previously, this return {
// means that something along the way failed in a step that is not upload_failed_run_skipped_because: "Code Scanning is not enabled.",
// owned by the Action, for example a manual build step. We };
// consider this a configuration error. }
core.exportVariable( if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") {
EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
);
// If the only enabled analysis kind is `code-quality`, then we shouldn't
// upload the failed SARIF to Code Scanning.
if (!isCodeScanningEnabled(config)) {
return {
upload_failed_run_skipped_because: "Code Scanning is not enabled.",
};
}
try {
return await maybeUploadFailedSarif(
config,
repositoryNwo,
features,
logger,
);
} catch (e) {
logger.debug(
`Failed to upload a SARIF file for this failed CodeQL code scanning run. ${e}`,
);
return createFailedUploadFailedSarifResult(e);
}
} else {
core.exportVariable(
EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.SuccessStatus,
);
return { return {
upload_failed_run_skipped_because: upload_failed_run_skipped_because:
"Analyze Action completed successfully", "Analyze Action completed successfully",
}; };
} }
try {
return await maybeUploadFailedSarif(
config,
repositoryNwo,
features,
logger,
);
} catch (e) {
logger.debug(
`Failed to upload a SARIF file for this failed CodeQL code scanning run. ${e}`,
);
return createFailedUploadFailedSarifResult(e);
}
} }
export async function run( export async function run(
@@ -335,20 +317,3 @@ async function removeUploadedSarif(
); );
} }
} }
/**
* Returns the final job status sent in the `init-post` Action, based on the
* current value of the JOB_STATUS environment variable. If the variable is
* unset, or if its value is not one of the JobStatus enum values, returns
* Unknown. Otherwise it returns the status set in the environment variable.
*/
export function getFinalJobStatus(): JobStatus {
const jobStatusFromEnvironment = process.env[EnvVar.JOB_STATUS];
if (
!jobStatusFromEnvironment ||
!Object.values(JobStatus).includes(jobStatusFromEnvironment as JobStatus)
) {
return JobStatus.UnknownStatus;
}
return jobStatusFromEnvironment as JobStatus;
}
+72 -4
View File
@@ -14,12 +14,13 @@ import {
import { getGitHubVersion } from "./api-client"; import { getGitHubVersion } from "./api-client";
import { CachingKind } from "./caching-utils"; import { CachingKind } from "./caching-utils";
import { getCodeQL } from "./codeql"; import { getCodeQL } from "./codeql";
import { Config, getConfig } from "./config-utils"; import { type Config, getConfig } from "./config-utils";
import * as debugArtifacts from "./debug-artifacts"; import * as debugArtifacts from "./debug-artifacts";
import { import {
DependencyCachingUsageReport, DependencyCachingUsageReport,
getDependencyCacheUsage, getDependencyCacheUsage,
} from "./dependency-caching"; } from "./dependency-caching";
import { EnvVar } from "./environment";
import { Features } from "./feature-flags"; import { Features } from "./feature-flags";
import * as gitUtils from "./git-utils"; import * as gitUtils from "./git-utils";
import * as initActionPostHelper from "./init-action-post-helper"; import * as initActionPostHelper from "./init-action-post-helper";
@@ -33,6 +34,7 @@ import {
getActionsStatus, getActionsStatus,
ActionName, ActionName,
getJobStatusDisplayName, getJobStatusDisplayName,
JobStatus,
} from "./status-report"; } from "./status-report";
import { checkDiskUsage, checkGitHubVersionInRange, wrapError } from "./util"; import { checkDiskUsage, checkGitHubVersionInRange, wrapError } from "./util";
@@ -85,7 +87,7 @@ async function run(startedAt: Date) {
logger, logger,
); );
// If we are analysing the default branch and some kind of caching is enabled, // If we are analyzing the default branch and some kind of caching is enabled,
// then try to determine our overall cache usage for dependency caches. We only // then try to determine our overall cache usage for dependency caches. We only
// do this under these circumstances to avoid slowing down analyses for PRs // do this under these circumstances to avoid slowing down analyses for PRs
// and where caching may not be enabled. // and where caching may not be enabled.
@@ -115,7 +117,7 @@ async function run(startedAt: Date) {
} }
return; return;
} }
const jobStatus = initActionPostHelper.getFinalJobStatus(); const jobStatus = getFinalJobStatus(config);
logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`); logger.info(`CodeQL job status was ${getJobStatusDisplayName(jobStatus)}.`);
const statusReportBase = await createStatusReportBase( const statusReportBase = await createStatusReportBase(
@@ -130,7 +132,7 @@ async function run(startedAt: Date) {
const statusReport: InitPostStatusReport = { const statusReport: InitPostStatusReport = {
...statusReportBase, ...statusReportBase,
...uploadFailedSarifResult, ...uploadFailedSarifResult,
job_status: initActionPostHelper.getFinalJobStatus(), job_status: jobStatus,
dependency_caching_usage: dependencyCachingUsage, dependency_caching_usage: dependencyCachingUsage,
}; };
logger.info("Sending status report for init-post step."); logger.info("Sending status report for init-post step.");
@@ -139,6 +141,72 @@ async function run(startedAt: Date) {
} }
} }
/**
* Determine the final job status to be reported in the status report.
*
* If the job status has already been set by another step, we use that.
* Otherwise, we determine the job status based on whether the analyze step
* completed successfully and whether we have a valid CodeQL config.
*/
function getFinalJobStatus(config: Config | undefined): JobStatus {
const existingJobStatus = getJobStatusFromEnvironment();
if (existingJobStatus !== undefined) {
return existingJobStatus;
}
let jobStatus: JobStatus;
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") {
core.exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
jobStatus = JobStatus.SuccessStatus;
} else if (config !== undefined) {
// - We have computed a CodeQL config
// - Analyze didn't complete successfully
// - The job status hasn't already been set to Failure/ConfigurationError
//
// This means that something along the way failed in a step that is not
// owned by the Action, for example a manual build step. We consider this a
// configuration error.
jobStatus = JobStatus.ConfigErrorStatus;
} else {
// If we didn't manage to compute a CodeQL config, it is unclear at this
// point why the analyze Action didn't complete.
// - One possibility is that the workflow run was cancelled. We could
// consider determining workflow cancellation using the GitHub API, but
// for now we treat all these cases as unknown.
// - Another possibility is that we're running a workflow that only runs
// `init`, for instance a workflow that was created before `setup-codeql`
// was available and uses `init` just to set up the CodeQL tools.
jobStatus = JobStatus.UnknownStatus;
}
// This shouldn't be necessary, but in the odd case that we run more than one
// `init` post step, ensure the job status is consistent between them.
core.exportVariable(EnvVar.JOB_STATUS, jobStatus);
return jobStatus;
}
/**
* Get the job status from the environment variable, if it has been set.
*
* If the job status is invalid, return `UnknownStatus`.
*/
function getJobStatusFromEnvironment(): JobStatus | undefined {
const jobStatusFromEnvironment = process.env[EnvVar.JOB_STATUS];
if (jobStatusFromEnvironment !== undefined) {
// Validate the job status from the environment. If it is invalid, return unknown.
if (
Object.values(JobStatus).includes(jobStatusFromEnvironment as JobStatus)
) {
return jobStatusFromEnvironment as JobStatus;
}
return JobStatus.UnknownStatus;
}
return undefined;
}
async function runWrapper() { async function runWrapper() {
const startedAt = new Date(); const startedAt = new Date();
const logger = getActionsLogger(); const logger = getActionsLogger();
+82 -18
View File
@@ -2,6 +2,7 @@ import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as github from "@actions/github";
import * as io from "@actions/io"; import * as io from "@actions/io";
import * as semver from "semver"; import * as semver from "semver";
import { v4 as uuidV4 } from "uuid"; import { v4 as uuidV4 } from "uuid";
@@ -30,18 +31,23 @@ import {
} from "./dependency-caching"; } from "./dependency-caching";
import { import {
addDiagnostic, addDiagnostic,
addNoLanguageDiagnostic,
flushDiagnostics, flushDiagnostics,
logUnwrittenDiagnostics, logUnwrittenDiagnostics,
makeDiagnostic, makeDiagnostic,
makeTelemetryDiagnostic, makeTelemetryDiagnostic,
} from "./diagnostics"; } from "./diagnostics";
import { EnvVar } from "./environment"; import { EnvVar } from "./environment";
import { Feature, Features } from "./feature-flags"; import { Feature, FeatureEnablement, Features } from "./feature-flags";
import { loadPropertiesFromApi } from "./feature-flags/properties"; import {
loadPropertiesFromApi,
RepositoryProperties,
} from "./feature-flags/properties";
import { import {
checkInstallPython311, checkInstallPython311,
checkPacksForOverlayCompatibility, checkPacksForOverlayCompatibility,
cleanupDatabaseClusterDirectory, cleanupDatabaseClusterDirectory,
getFileCoverageInformationEnabled,
initCodeQL, initCodeQL,
initConfig, initConfig,
runDatabaseInitCluster, runDatabaseInitCluster,
@@ -53,7 +59,7 @@ import {
OverlayBaseDatabaseDownloadStats, OverlayBaseDatabaseDownloadStats,
OverlayDatabaseMode, OverlayDatabaseMode,
} from "./overlay-database-utils"; } from "./overlay-database-utils";
import { getRepositoryNwo } from "./repository"; import { getRepositoryNwo, RepositoryNwo } from "./repository";
import { ToolsSource } from "./setup-codeql"; import { ToolsSource } from "./setup-codeql";
import { import {
ActionName, ActionName,
@@ -87,6 +93,8 @@ import {
checkActionVersion, checkActionVersion,
getErrorMessage, getErrorMessage,
BuildMode, BuildMode,
GitHubVersion,
Result,
} from "./util"; } from "./util";
import { checkWorkflow } from "./workflow"; import { checkWorkflow } from "./workflow";
@@ -237,12 +245,12 @@ async function run(startedAt: Date) {
); );
// Fetch the values of known repository properties that affect us. // Fetch the values of known repository properties that affect us.
const enableRepoProps = await features.getValue( const repositoryPropertiesResult = await loadRepositoryProperties(
Feature.UseRepositoryProperties, repositoryNwo,
gitHubVersion,
features,
logger,
); );
const repositoryProperties = enableRepoProps
? await loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo)
: {};
// Create a unique identifier for this run. // Create a unique identifier for this run.
const jobRunUuid = uuidV4(); const jobRunUuid = uuidV4();
@@ -334,6 +342,7 @@ async function run(startedAt: Date) {
} }
analysisKinds = await getAnalysisKinds(logger); analysisKinds = await getAnalysisKinds(logger);
const debugMode = getOptionalInput("debug") === "true" || core.isDebug();
config = await initConfig(features, { config = await initConfig(features, {
analysisKinds, analysisKinds,
languagesInput: getOptionalInput("languages"), languagesInput: getOptionalInput("languages"),
@@ -350,7 +359,7 @@ async function run(startedAt: Date) {
// - The `init` Action is passed `debug: true`. // - The `init` Action is passed `debug: true`.
// - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow), // - Actions step debugging is enabled (e.g. by [enabling debug logging for a rerun](https://docs.github.com/en/actions/managing-workflow-runs/re-running-workflows-and-jobs#re-running-all-the-jobs-in-a-workflow),
// or by setting the `ACTIONS_STEP_DEBUG` secret to `true`). // or by setting the `ACTIONS_STEP_DEBUG` secret to `true`).
debugMode: getOptionalInput("debug") === "true" || core.isDebug(), debugMode,
debugArtifactName: debugArtifactName:
getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME, getOptionalInput("debug-artifact-name") || DEFAULT_DEBUG_ARTIFACT_NAME,
debugDatabaseName: debugDatabaseName:
@@ -363,10 +372,28 @@ async function run(startedAt: Date) {
githubVersion: gitHubVersion, githubVersion: gitHubVersion,
apiDetails, apiDetails,
features, features,
repositoryProperties, repositoryProperties: repositoryPropertiesResult.orElse({}),
enableFileCoverageInformation: await getFileCoverageInformationEnabled(
debugMode,
repositoryNwo,
features,
),
logger, logger,
}); });
if (repositoryPropertiesResult.isFailure()) {
addNoLanguageDiagnostic(
config,
makeTelemetryDiagnostic(
"codeql-action/repository-properties-load-failure",
"Failed to load repository properties",
{
error: getErrorMessage(repositoryPropertiesResult.value),
},
),
);
}
await checkInstallPython311(config.languages, codeql); await checkInstallPython311(config.languages, codeql);
} catch (unwrappedError) { } catch (unwrappedError) {
const error = wrapError(unwrappedError); const error = wrapError(unwrappedError);
@@ -429,11 +456,8 @@ async function run(startedAt: Date) {
// Log CodeQL download telemetry, if appropriate // Log CodeQL download telemetry, if appropriate
if (toolsDownloadStatusReport) { if (toolsDownloadStatusReport) {
addDiagnostic( addNoLanguageDiagnostic(
config, config,
// Arbitrarily choose the first language. We could also choose all languages, but that
// increases the risk of misinterpreting the data.
config.languages[0],
makeTelemetryDiagnostic( makeTelemetryDiagnostic(
"codeql-action/bundle-download-telemetry", "codeql-action/bundle-download-telemetry",
"CodeQL bundle download telemetry", "CodeQL bundle download telemetry",
@@ -775,6 +799,49 @@ async function run(startedAt: Date) {
); );
} }
/**
* Loads [repository properties](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization) if applicable.
*/
async function loadRepositoryProperties(
repositoryNwo: RepositoryNwo,
gitHubVersion: GitHubVersion,
features: FeatureEnablement,
logger: Logger,
): Promise<Result<RepositoryProperties, unknown>> {
// See if we can skip loading repository properties early. In particular,
// repositories owned by users cannot have repository properties, so we can
// skip the API call entirely in that case.
const repositoryOwnerType = github.context.payload.repository?.owner.type;
logger.debug(
`Repository owner type is '${repositoryOwnerType ?? "unknown"}'.`,
);
if (repositoryOwnerType === "User") {
logger.debug(
"Skipping loading repository properties because the repository is owned by a user and " +
"therefore cannot have repository properties.",
);
return Result.success({});
}
if (!(await features.getValue(Feature.UseRepositoryProperties))) {
logger.debug(
"Skipping loading repository properties because the UseRepositoryProperties feature flag is disabled.",
);
return Result.success({});
}
try {
return Result.success(
await loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo),
);
} catch (error) {
logger.warning(
`Failed to load repository properties: ${getErrorMessage(error)}`,
);
return Result.failure(error);
}
}
function getTrapCachingEnabled(): boolean { function getTrapCachingEnabled(): boolean {
// If the workflow specified something always respect that // If the workflow specified something always respect that
const trapCaching = getOptionalInput("trap-caching"); const trapCaching = getOptionalInput("trap-caching");
@@ -791,11 +858,8 @@ async function recordZstdAvailability(
config: configUtils.Config, config: configUtils.Config,
zstdAvailability: ZstdAvailability, zstdAvailability: ZstdAvailability,
) { ) {
addDiagnostic( addNoLanguageDiagnostic(
config, config,
// Arbitrarily choose the first language. We could also choose all languages, but that
// increases the risk of misinterpreting the data.
config.languages[0],
makeTelemetryDiagnostic( makeTelemetryDiagnostic(
"codeql-action/zstd-availability", "codeql-action/zstd-availability",
"Zstandard availability", "Zstandard availability",
+64
View File
@@ -2,14 +2,20 @@ import * as fs from "fs";
import path from "path"; import path from "path";
import test, { ExecutionContext } from "ava"; import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { createStubCodeQL } from "./codeql"; import { createStubCodeQL } from "./codeql";
import { Feature } from "./feature-flags";
import { import {
checkPacksForOverlayCompatibility, checkPacksForOverlayCompatibility,
cleanupDatabaseClusterDirectory, cleanupDatabaseClusterDirectory,
getFileCoverageInformationEnabled,
} from "./init"; } from "./init";
import { KnownLanguage } from "./languages"; import { KnownLanguage } from "./languages";
import { parseRepositoryNwo } from "./repository";
import { import {
createFeatures,
LoggedMessage, LoggedMessage,
createTestConfig, createTestConfig,
getRecordingLogger, getRecordingLogger,
@@ -442,3 +448,61 @@ test(
expectedResult: true, expectedResult: true,
}, },
); );
test("file coverage information enabled when debugMode is true", async (t) => {
t.true(
await getFileCoverageInformationEnabled(
true, // debugMode
parseRepositoryNwo("github/codeql-action"),
createFeatures([Feature.SkipFileCoverageOnPrs]),
),
);
});
test("file coverage information enabled when not analyzing a pull request", async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(false);
t.true(
await getFileCoverageInformationEnabled(
false, // debugMode
parseRepositoryNwo("github/codeql-action"),
createFeatures([Feature.SkipFileCoverageOnPrs]),
),
);
});
test("file coverage information enabled when owner is not 'github'", async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true);
t.true(
await getFileCoverageInformationEnabled(
false, // debugMode
parseRepositoryNwo("other-org/some-repo"),
createFeatures([Feature.SkipFileCoverageOnPrs]),
),
);
});
test("file coverage information enabled when feature flag is not enabled", async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true);
t.true(
await getFileCoverageInformationEnabled(
false, // debugMode
parseRepositoryNwo("github/codeql-action"),
createFeatures([]),
),
);
});
test("file coverage information disabled when all conditions for skipping are met", async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(true);
t.false(
await getFileCoverageInformationEnabled(
false, // debugMode
parseRepositoryNwo("github/codeql-action"),
createFeatures([Feature.SkipFileCoverageOnPrs]),
),
);
});
+29 -2
View File
@@ -5,13 +5,22 @@ import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as io from "@actions/io"; import * as io from "@actions/io";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { getOptionalInput, isSelfHostedRunner } from "./actions-util"; import {
getOptionalInput,
isAnalyzingPullRequest,
isSelfHostedRunner,
} from "./actions-util";
import { GitHubApiDetails } from "./api-client"; import { GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql"; import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils"; import * as configUtils from "./config-utils";
import { CodeQLDefaultVersionInfo, FeatureEnablement } from "./feature-flags"; import {
CodeQLDefaultVersionInfo,
Feature,
FeatureEnablement,
} from "./feature-flags";
import { KnownLanguage, Language } from "./languages"; import { KnownLanguage, Language } from "./languages";
import { Logger, withGroupAsync } from "./logging"; import { Logger, withGroupAsync } from "./logging";
import { RepositoryNwo } from "./repository";
import { ToolsSource } from "./setup-codeql"; import { ToolsSource } from "./setup-codeql";
import { ZstdAvailability } from "./tar"; import { ZstdAvailability } from "./tar";
import { ToolsDownloadStatusReport } from "./tools-download"; import { ToolsDownloadStatusReport } from "./tools-download";
@@ -288,3 +297,21 @@ export function cleanupDatabaseClusterDirectory(
} }
} }
} }
export async function getFileCoverageInformationEnabled(
debugMode: boolean,
repositoryNwo: RepositoryNwo,
features: FeatureEnablement,
): Promise<boolean> {
return (
// Always enable file coverage information in debug mode
debugMode ||
// We're most interested in speeding up PRs, and we want to keep
// submitting file coverage information for the default branch since
// it is used to populate the status page.
!isAnalyzingPullRequest() ||
// For now, restrict this feature to the GitHub org
repositoryNwo.owner !== "github" ||
!(await features.getValue(Feature.SkipFileCoverageOnPrs))
);
}
-1
View File
@@ -34,7 +34,6 @@ const expectedFeatureEnablement: FeatureEnablement = initializeFeatures(
true, true,
) as FeatureEnablement; ) as FeatureEnablement;
expectedFeatureEnablement.getValue = function (feature: Feature) { expectedFeatureEnablement.getValue = function (feature: Feature) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return expectedFeatureEnablement[feature]; return expectedFeatureEnablement[feature];
}; };
test.beforeEach(() => { test.beforeEach(() => {
+37 -2
View File
@@ -7,7 +7,12 @@ import { KnownLanguage } from "./languages";
import { getRunnerLogger } from "./logging"; import { getRunnerLogger } from "./logging";
import * as startProxyExports from "./start-proxy"; import * as startProxyExports from "./start-proxy";
import { parseLanguage } from "./start-proxy"; import { parseLanguage } from "./start-proxy";
import { setupTests } from "./testing-utils"; import {
checkExpectedLogMessages,
getRecordingLogger,
makeTestToken,
setupTests,
} from "./testing-utils";
setupTests(test); setupTests(test);
@@ -174,6 +179,37 @@ test("getCredentials throws an error when non-printable characters are used", as
} }
}); });
test("getCredentials logs a warning when a PAT is used without a username", async (t) => {
const loggedMessages = [];
const logger = getRecordingLogger(loggedMessages);
const likelyWrongCredentials = toEncodedJSON([
{
type: "git_server",
host: "https://github.com/",
password: `ghp_${makeTestToken()}`,
},
]);
const results = startProxyExports.getCredentials(
logger,
undefined,
likelyWrongCredentials,
undefined,
);
// The configuration should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
t.assert(results[0].password?.startsWith("ghp_"));
// A warning should have been logged.
checkExpectedLogMessages(t, loggedMessages, [
"using a GitHub Personal Access Token (PAT), but no username was provided",
]);
});
test("parseLanguage", async (t) => { test("parseLanguage", async (t) => {
// Exact matches // Exact matches
t.deepEqual(parseLanguage("csharp"), KnownLanguage.csharp); t.deepEqual(parseLanguage("csharp"), KnownLanguage.csharp);
@@ -213,7 +249,6 @@ function mockGetReleaseByTag(assets?: Array<{ name: string; url?: string }>) {
url: "GET /repos/:owner/:repo/releases/tags/:tag", url: "GET /repos/:owner/:repo/releases/tags/:tag",
}); });
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
mockClient.returns({ mockClient.returns({
rest: { rest: {
repos: { repos: {
+21
View File
@@ -1,6 +1,7 @@
import * as core from "@actions/core"; import * as core from "@actions/core";
import { getApiClient } from "./api-client"; import { getApiClient } from "./api-client";
import * as artifactScanner from "./artifact-scanner";
import * as defaults from "./defaults.json"; import * as defaults from "./defaults.json";
import { KnownLanguage } from "./languages"; import { KnownLanguage } from "./languages";
import { Logger } from "./logging"; import { Logger } from "./logging";
@@ -62,6 +63,13 @@ export function parseLanguage(language: string): KnownLanguage | undefined {
return undefined; return undefined;
} }
function isPAT(value: string) {
return artifactScanner.isAuthToken(value, [
artifactScanner.GITHUB_PAT_CLASSIC_PATTERN,
artifactScanner.GITHUB_PAT_FINE_GRAINED_PATTERN,
]);
}
const LANGUAGE_TO_REGISTRY_TYPE: Partial<Record<KnownLanguage, string[]>> = { const LANGUAGE_TO_REGISTRY_TYPE: Partial<Record<KnownLanguage, string[]>> = {
java: ["maven_repository"], java: ["maven_repository"],
csharp: ["nuget_feed"], csharp: ["nuget_feed"],
@@ -161,6 +169,19 @@ export function getCredentials(
); );
} }
// If the password or token looks like a GitHub PAT, warn if no username is configured.
if (
!isDefined(e.username) &&
((isDefined(e.password) && isPAT(e.password)) ||
(isDefined(e.token) && isPAT(e.token)))
) {
logger.warning(
`A ${e.type} private registry is configured for ${e.host || e.url} using a GitHub Personal Access Token (PAT), but no username was provided. ` +
`This may not work correctly. When configuring a private registry using a PAT, select "Username and password" and enter the username of the user ` +
`who generated the PAT.`,
);
}
out.push({ out.push({
type: e.type, type: e.type,
host: e.host, host: e.host,
+7 -1
View File
@@ -269,7 +269,6 @@ export function mockLanguagesInRepo(languages: string[]) {
url: "GET /repos/:owner/:repo/languages", url: "GET /repos/:owner/:repo/languages",
}); });
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
mockClient.returns({ mockClient.returns({
rest: { rest: {
repos: { repos: {
@@ -408,7 +407,14 @@ export function createTestConfig(overrides: Partial<Config>): Config {
overlayDatabaseMode: OverlayDatabaseMode.None, overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false, useOverlayDatabaseCaching: false,
repositoryProperties: {}, repositoryProperties: {},
enableFileCoverageInformation: true,
} satisfies Config, } satisfies Config,
overrides, overrides,
); );
} }
export function makeTestToken(length: number = 36) {
const chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return chars.repeat(Math.ceil(length / chars.length)).slice(0, length);
}
-1
View File
@@ -1057,7 +1057,6 @@ function handleProcessingResultForUnsuccessfulExecution(
status === "failed" && status === "failed" &&
Array.isArray(response.data.errors) && Array.isArray(response.data.errors) &&
response.data.errors.length === 1 && response.data.errors.length === 1 &&
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
response.data.errors[0].toString().startsWith("unsuccessful execution") response.data.errors[0].toString().startsWith("unsuccessful execution")
) { ) {
logger.info( logger.info(
+25
View File
@@ -563,3 +563,28 @@ test("joinAtMost - truncates list if array is > than limit", (t) => {
t.assert(result.includes("test5")); t.assert(result.includes("test5"));
t.false(result.includes("test6")); t.false(result.includes("test6"));
}); });
test("Result.success creates a success result", (t) => {
const result = util.Result.success("test value");
t.true(result.isSuccess());
t.false(result.isFailure());
t.is(result.value, "test value");
});
test("Result.failure creates a failure result", (t) => {
const error = new Error("test error");
const result = util.Result.failure(error);
t.false(result.isSuccess());
t.true(result.isFailure());
t.is(result.value, error);
});
test("Result.orElse returns the value for a success result", (t) => {
const result = util.Result.success("success value");
t.is(result.orElse("default value"), "success value");
});
test("Result.orElse returns the default value for a failure result", (t) => {
const result = util.Result.failure(new Error("test error"));
t.is(result.orElse("default value"), "default value");
});
+40
View File
@@ -1292,3 +1292,43 @@ export function joinAtMost(
return array.join(separator); return array.join(separator);
} }
/** A success result. */
type Success<T> = Result<T, never>;
/** A failure result. */
type Failure<E> = Result<never, E>;
/**
* A simple result type representing either a success or a failure.
*/
export class Result<T, E> {
private constructor(
private readonly _ok: boolean,
public readonly value: T | E,
) {}
/** Creates a success result. */
static success<T>(value: T): Success<T> {
return new Result(true, value) as Success<T>;
}
/** Creates a failure result. */
static failure<E>(value: E): Failure<E> {
return new Result(false, value) as Failure<E>;
}
/** Whether this result represents a success. */
isSuccess(): this is Success<T> {
return this._ok;
}
/** Whether this result represents a failure. */
isFailure(): this is Failure<E> {
return !this._ok;
}
/** Get the value if this is a success, or return the default value if this is a failure. */
orElse<U>(defaultValue: U): T | U {
return this.isSuccess() ? this.value : defaultValue;
}
}
+6 -2
View File
@@ -1,8 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Basic Options */ /* Basic Options */
"lib": ["ES2021"], "lib": ["ES2022"],
"target": "ES2021", "target": "ES2022",
"module": "commonjs", "module": "commonjs",
"outDir": "./build", "outDir": "./build",
"rootDir": "./src", "rootDir": "./src",
@@ -25,8 +25,12 @@
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */ /* Module Resolution Options */
"baseUrl": ".", /* Base directory to resolve non-absolute module names. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true, "resolveJsonModule": true,
"paths": {
"@octokit/core/types": ["./node_modules/@octokit/core/dist-types/types.d.ts"]
},
}, },
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }