Compare commits

...

186 Commits

Author SHA1 Message Date
Edoardo Pirovano
1e61ecb0c1 Merge pull request #603 from github/mergeback/v1.0.4-to-main-03450ff6
Mergeback v1.0.4 refs/heads/v1 into main
2021-06-28 16:57:01 +01:00
Edoardo Pirovano
8cccc0664b Merge branch 'main' into mergeback/v1.0.4-to-main-03450ff6 2021-06-28 16:42:39 +01:00
Andrew Eisenberg
3a8e1847c5 Merge pull request #599 from github/aeisenberg/readme-missing-analysis
Update readme to include section on missing analysis
2021-06-28 08:30:15 -07:00
github-actions[bot]
5c3c29fd3f 1.0.5 2021-06-28 15:23:49 +00:00
github-actions[bot]
d11b2ce6a3 Update changelog and version after v1.0.4 2021-06-28 15:23:47 +00:00
Edoardo Pirovano
03450ff6ed Merge pull request #601 from github/update-v1.0.4-7726ece0
Merge main into v1
2021-06-28 16:23:20 +01:00
Andrew Eisenberg
571fe400df Merge branch 'main' into aeisenberg/readme-missing-analysis 2021-06-28 08:18:18 -07:00
Edoardo Pirovano
440ccbd910 Prepare CHANGELOG for 1.0.4 2021-06-28 16:06:44 +01:00
github-actions[bot]
6017205208 1.0.4 2021-06-28 16:05:56 +01:00
Andrew Eisenberg
7726ece0ab Merge pull request #591 from github/aeisenberg/pack-in-inputs
Add new `packs` input to init action
2021-06-25 10:52:19 -07:00
Andrew Eisenberg
7c391e9640 Update readme to include section on missing analysis
Fixes #598
2021-06-25 10:44:47 -07:00
Andrew Eisenberg
67312df7cf Merge branch 'main' into aeisenberg/pack-in-inputs 2021-06-25 10:30:24 -07:00
Andrew Eisenberg
4087f37d90 Add extra integration test for packaging
Also, update the options and inputs documentation.
2021-06-25 10:07:51 -07:00
Edoardo Pirovano
85ac9fe26e Remove misleading comment. 2021-06-25 14:28:43 +01:00
Edoardo Pirovano
40852fa52a Improve error messages from CLI invocations 2021-06-24 23:38:13 +01:00
Andrew Eisenberg
db80a9a7c3 Merge pull request #594 from github/simon-engledew/fix-runner-temp-missing
Restore original getCodeQLActionRepository behaviour
2021-06-24 13:58:42 -07:00
Andrew Eisenberg
af32a29f03 Merge branch 'main' into simon-engledew/fix-runner-temp-missing 2021-06-24 13:48:45 -07:00
Arthur Baars
590c245b56 Merge pull request #593 from github/aibaars/ruby-is-interpreted
Add Ruby to 'isInterpretedLanguage'
2021-06-24 19:23:57 +02:00
Arthur Baars
a1f71cfecf Add Ruby to 'isInterpretedLanguage' 2021-06-24 19:13:05 +02:00
Simon Engledew
26ade03b50 Just reverse test case 2021-06-24 18:00:10 +01:00
Simon Engledew
9200db3ec4 Restore original getCodeQLActionRepository behaviour 2021-06-24 17:52:48 +01:00
Andrew Eisenberg
ac402bf222 Merge pull request #586 from edoardopirovano/csharp-loc
Fix C# line counting and add test
2021-06-23 17:29:02 -07:00
Andrew Eisenberg
9f37000f6b Fix dependencies 2021-06-23 16:38:32 -07:00
Andrew Eisenberg
c5434c91d8 Merge branch 'main' into csharp-loc 2021-06-23 16:22:14 -07:00
Andrew Eisenberg
e38356b367 Update lock file 2021-06-23 16:11:57 -07:00
Andrew Eisenberg
6e577cfca3 Add new packs input to init action
This input allows users to specify which packs to run. It works in
unison with the packs block of the config file and it is similar to
how `queries` works. They both use `+` in the same way.

Note that the `#TODO` in the pr check is still around, but the CLI
is available. I will remove the TODO in the next commit.
2021-06-23 16:08:35 -07:00
Edoardo Pirovano
68b68732c6 Fix C# line counting and add test 2021-06-23 23:39:44 +01:00
Andrew Eisenberg
7729b51956 Merge pull request #588 from github/mergeback/v1.0.3-to-main-cf6e0194
Mergeback v1.0.3 refs/heads/v1 into main
2021-06-23 08:23:18 -07:00
Andrew Eisenberg
c98b43187d Merge branch 'main' into mergeback/v1.0.3-to-main-cf6e0194 2021-06-23 08:08:49 -07:00
Chris Gavin
e684c09260 Merge pull request #587 from github/toolcache-upgrade
Upgrade the tool cache library and use it to download the CodeQL bundle.
2021-06-23 16:07:26 +01:00
github-actions[bot]
1496843315 1.0.4 2021-06-23 14:56:35 +00:00
github-actions[bot]
f5a5d3ad5f Update changelog and version after v1.0.3 2021-06-23 14:56:23 +00:00
Andrew Eisenberg
cf6e019480 Merge pull request #585 from github/update-v1.0.3-d623a7a3
Merge main into v1
2021-06-23 07:55:54 -07:00
Chris Gavin
59560e54ac Replace custom tool download method with the one in the tool cache library. 2021-06-23 14:28:37 +01:00
Chris Gavin
476f13ea18 Upgrade Actions Tool Cache. 2021-06-23 14:28:33 +01:00
github-actions[bot]
a12bb22724 1.0.3 2021-06-23 09:42:14 +00:00
Andrew Eisenberg
d623a7a3f7 Merge pull request #583 from github/aeisenberg/changelog-template
Update changelog template
2021-06-22 14:40:52 -07:00
Andrew Eisenberg
629f582c03 Update changelog template
The changelog for an empty version will now be:

```
No user facing changes.
```

And this will appear in the final changelog when there is an actual release.
The benefits are that users will see regular release cycles and know
how old versions are even if there's no changes for a particular version

If we find that we are going months without any user facing changes, but
we have non-visible changes, then we can rethink this strategy.
But I think this is nicer than having empty sections for a version.
2021-06-22 14:25:06 -07:00
Henning Makholm
9821b8c68c Merge pull request #582 from github/hmakholm/pr/2.5.6
Update CodeQL bundle to 20210622 / 2.5.6
2021-06-22 18:43:19 +02:00
Henry Mercer
1cd2cd12b4 Merge branch 'main' into hmakholm/pr/2.5.6 2021-06-22 17:12:00 +01:00
Robert
171619a51a Merge pull request #578 from github/upload-database
Upload CodeQL databases - mk2
2021-06-22 17:09:46 +01:00
Henning Makholm
8d50a5fd90 Update CodeQL bundle to 20210622 / 2.5.6 2021-06-22 17:27:16 +02:00
Robert
00791d5d56 remove old lib file 2021-06-22 13:45:47 +01:00
Robert
146c897909 Upload CodeQL databases 2021-06-22 13:05:12 +01:00
Andrew Eisenberg
b2d10b39b0 Merge pull request #571 from github/mergeback/v1.0.2-to-main-37f75f17
Mergeback v1.0.2 refs/heads/v1 into main
2021-06-21 08:42:17 -07:00
Andrew Eisenberg
b2e7277fb1 Merge branch 'main' into mergeback/v1.0.2-to-main-37f75f17 2021-06-21 08:29:15 -07:00
Robert
dbc4fdad80 Merge pull request #577 from github/revert-573-upload-database
Revert "Upload CodeQL databases"
2021-06-21 10:58:55 +01:00
Robert
d893508e3a Revert "Upload CodeQL databases" 2021-06-21 10:26:02 +01:00
Robert
f6d1bad81b Merge pull request #573 from github/upload-database
Upload CodeQL databases
2021-06-21 08:45:03 +01:00
Robert
f3cd5fa001 Add workflow input to disable uploads 2021-06-18 09:56:15 +01:00
Robert
33ac512514 Merge branch 'main' into upload-database 2021-06-18 09:50:05 +01:00
Andrew Eisenberg
6a7c2369bf Merge pull request #569 from github/aeisenberg/add-codeowners
Add a CODEOWNERS file
2021-06-17 11:36:23 -07:00
github-actions[bot]
4954c371d1 1.0.3 2021-06-17 18:01:57 +00:00
github-actions[bot]
c35646fe13 Update changelog and version after v1.0.2 2021-06-17 18:01:56 +00:00
Andrew Eisenberg
37f75f1702 Merge pull request #570 from github/update-v1.0.2-0b1f4a01
Merge main into v1
2021-06-17 11:01:25 -07:00
github-actions[bot]
028a76e6db 1.0.2 2021-06-17 10:39:32 -07:00
Andrew Eisenberg
9c28349a87 Merge branch 'main' into aeisenberg/add-codeowners 2021-06-17 10:27:42 -07:00
Andrew Eisenberg
0b1f4a016a Merge pull request #566 from github/aeisenberg/update-release-branch-fix
Fix update-release-branch-fix.py
2021-06-17 10:22:26 -07:00
Andrew Eisenberg
b4914d76a2 Add a CODEOWNERS file 2021-06-17 10:19:01 -07:00
Robert
69c30da5ad Merge pull request #565 from github/robertbrignull/upload_ghes
Only attempt to upload on dotcom
2021-06-17 12:42:23 +01:00
Robert
6fc1280a3c Merge pull request #564 from github/robertbrignull/workflow_event_error
Provide a better error message
2021-06-17 09:36:47 +01:00
Andrew Eisenberg
efea9238bc Fix custom version of CLI to use for package testing
This can be removed when 2.5.6 is released.
2021-06-16 14:56:52 -07:00
Andrew Eisenberg
d16268b273 Fix update-release-branch-fix.py
This change ensures that the the script can handle
commits with no committer in them. This will happen
for some commits that are auto-generated during
PRs.
2021-06-16 10:38:18 -07:00
Robert
b985a67b97 Only attempt to upload on dotcom 2021-06-16 17:24:26 +01:00
Robert
c989ee7b39 Provide a better error message 2021-06-16 17:00:26 +01:00
Robert
366b68eda0 Merge pull request #563 from github/robertbrignull/check_default_branch
Check if on default branch before uploading database
2021-06-16 15:11:45 +01:00
Robert
d693b3cb0d Check if on default branch before uploading database 2021-06-16 14:43:42 +01:00
Andrew Eisenberg
e284efba72 Merge pull request #545 from github/aeisenberg/pack-run
Allow the codeql-action to run packages
2021-06-10 11:24:56 -07:00
Andrew Eisenberg
20aafcd90c Remove unnecessary type assertions 2021-06-10 11:15:03 -07:00
Robin Neatherway
429471162a Update cleanup to bundle 2021-06-10 17:09:58 +01:00
Robert
2a9a602a5e Upload databases from analyze action 2021-06-10 16:09:58 +01:00
Andrew Eisenberg
6a1c0700c3 Avoid running mergeback workflow on PR
This was causing the workflow to run and create tags after merging
main into a branch.
2021-06-09 14:38:09 -07:00
Andrew Eisenberg
23cdd6bab6 Remove two log entries
Cleans up the output logs even more. These entries don't add any more
information since everything is grouped now.
2021-06-09 14:32:08 -07:00
Andrew Eisenberg
a2e96a4c78 Add pack download to its own log group
Also, make the baseline count message less awkward sounding.
2021-06-09 14:13:05 -07:00
Andrew Eisenberg
96e7de35af Use nullish conversion for packs
Slightly simplifies the `parsePacks` function.
2021-06-09 13:18:27 -07:00
Andrew Eisenberg
49b2220f92 Refactor codeql.ts
Extract a `runTool` function that captures the stdout and returns it.
A small refactoring that reduces copied code.
2021-06-09 13:17:25 -07:00
Andrew Eisenberg
db01c78de0 Remove unneeded action input in PR check 2021-06-09 13:10:57 -07:00
Andrew Eisenberg
82388fd94a Merge remote-tracking branch 'upstream/main' into aeisenberg/pack-run 2021-06-09 12:43:17 -07:00
Edoardo Pirovano
babcc1b793 Add --finalize-dataset to database finalize call 2021-06-09 16:52:39 +01:00
Edoardo Pirovano
06df98a513 Add new log grouping for DB cleanup 2021-06-09 16:10:22 +01:00
Edoardo Pirovano
0ea20c5b32 Add intepret-results timings to status reports 2021-06-09 10:40:15 +01:00
Andrew Eisenberg
d42f654f7a Add an integration test for packaging
Uses two pre-existing packages to run some simple queries on a javascript
database.
2021-06-08 12:34:07 -07:00
Andrew Eisenberg
1cc5f1d5dd Packaging: Address review comments
1. Better malformed data guard for PackDownloadOutput
2. Fix Packs type
3. Remove TODO in init-action
2021-06-08 10:00:22 -07:00
Edoardo Pirovano
2cc885d66e Replace analyze with run-queries and interpret-results 2021-06-08 09:25:17 +01:00
Edoardo Pirovano
c09500540c Some refactoring in fingerprint computation 2021-06-08 00:09:27 +01:00
Andrew Eisenberg
9c13fefc68 Merge pull request #554 from github/mergeback/v1.0.1-to-main-ece2addc
Mergeback v1.0.1 refs/heads/v1 into main
2021-06-07 14:14:54 -07:00
Andrew Eisenberg
a69f472ee9 Merge branch 'main' into mergeback/v1.0.1-to-main-ece2addc 2021-06-07 14:01:04 -07:00
github-actions[bot]
fbb9046bf6 1.0.2 2021-06-07 20:59:15 +00:00
github-actions[bot]
9e6b46a9e6 Update changelog and version after v1.0.1 2021-06-07 20:59:13 +00:00
Andrew Eisenberg
ece2addcff Merge pull request #553 from github/aeisenberg/no-quotes
Remove quotes around `$DRAFT` argument
2021-06-07 13:54:37 -07:00
Andrew Eisenberg
74764ac0eb Remove quotes around $DRAFT argument
gh will complain if there is an empty `""`, which is the case if
`$DRAFT` is unset.
2021-06-07 13:53:47 -07:00
Chris Gavin
675843d09a Merge pull request #549 from github/update-v1.0.1-242fd828
Merge main into v1
2021-06-07 16:26:37 +01:00
Chris Gavin
511fe43abe Empty commit to trigger CI. 2021-06-07 16:14:10 +01:00
Edoardo Pirovano
02e8dcfe9c Fix out of memory in hash computation 2021-06-07 15:12:45 +01:00
github-actions[bot]
68d7c5f620 1.0.1 2021-06-07 09:30:01 +00:00
Chris Gavin
242fd828aa Merge pull request #547 from github/retrying-fix
Add back retrying.
2021-06-07 08:04:21 +01:00
Chris Gavin
48efe6e282 Merge branch 'main' into retrying-fix 2021-06-07 07:47:18 +01:00
Chris Gavin
f8c65b775d Fix stub in tests. 2021-06-07 07:14:44 +01:00
Andrew Eisenberg
d87945e9fd Run the pack download command 2021-06-06 09:27:52 -07:00
Edoardo Pirovano
1644ade514 Add --sarif-group-rules-by-pack flag 2021-06-06 09:56:54 +01:00
Andrew Eisenberg
06687e95c8 Avoid using SemVer instances
Use strings instead. They are easier to serialize and deserialize.
2021-06-04 13:34:55 -07:00
Andrew Eisenberg
9b5753ab00 Fix logic for calculating if there are queries to run
During the analyze phase.
2021-06-04 13:23:35 -07:00
Edoardo Pirovano
ddb83a462d Cleanup CodeQL DBs and output their location for later steps 2021-06-04 18:54:15 +01:00
Andrew Eisenberg
6cee818bf3 Add better comments and error messages for pack-related changes 2021-06-04 10:18:24 -07:00
Chris Gavin
41dff7fce3 Add back retrying. 2021-06-04 15:51:51 +01:00
Andrew Eisenberg
86a804f9a7 Allow the codeql-action to run packages
This commit adds a `packs` option to the codeql-config.yml file. Users
can specify a list of ql packs to include in the analysis.

For a single language analysis, the packs property looks like this:

```yaml
packs:
  - pack-scope/pack-name1@1.2.3
  - pack-scope/pack-name2   # no explicit version means download the latest
```

For multi-language analysis, you must key the packs block by lanaguage:

```yaml
packs:
  cpp:
    - pack-scope/pack-name1@1.2.3
    - pack-scope/pack-name2
  java:
    - pack-scope/pack-name3@1.2.3
    - pack-scope/pack-name4
```

This implementation adds a new analysis run (alongside custom and 
builtin runs). The unit tests indicate that the correct commands are
being run, but I have not actually tried this with a real CLI.

Also, convert `instanceof Array` to `Array.isArray` since that is
sightly better in some situations. See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#instanceof_vs_isarray
2021-06-03 15:46:40 -07:00
Andrew Eisenberg
cbdf0df97b Merge pull request #539 from github/aeisenberg/env-vars
Add environment variables to signal feature and version to the CLI
2021-06-03 15:35:17 -07:00
Andrew Eisenberg
f60ef170b0 Cleaning up comments around env vars
Also, move `getTemporaryDirectory` back to `actions-util`.
2021-06-03 11:33:20 -07:00
Andrew Eisenberg
cc0733fd12 Fix Unguarded actions library use code scanning error
Must access the env var directly in order to avoid recursive calls to 
`getRequiredEnvParam`.
2021-06-02 11:55:32 -07:00
Andrew Eisenberg
082575fbc3 Merge branch 'main' into aeisenberg/env-vars 2021-06-02 11:40:40 -07:00
Andrew Eisenberg
2c2ebdc5c5 Remove local environment running
This is a functionality that never worked perfectly and hasn't been
used for a while.

This allows developers to run the action on their local machine, but
the run was always flaky and never 100% mirrored what was happening on
the actions runner.
2021-06-02 11:26:11 -07:00
Andrew Eisenberg
3708898bf2 Add environment variables to signal feature and version to the CLI
This PR ensures environment variables are set before any invocation of
the CLI.  Here is a list of vars that are set:

https://github.com/github/codeql-coreql-team/issues/1124#issuecomment-852463521

This ensures the CLI knows the features and versions of the containing
actions/runner.

Additionally:

- Fix the user agent so that it more closely aligns with user agent
  spec
- Refactor environment variable initialization so that it all happens in
  one place and call.
- Move Mode, getRequiredEnvParam, setMode, getMode out of actions-util
  and into util. actions-util is meant for utils only called by the
  action, not the runner.

The `prepareLocalRunEnvironment()` method is most likely deprecated and
should be removed. I originally added it because I had a way of working
where I would run the action from my local machine to test out changes,
but this was always a little flaky. So, I no longer use this way of
working. I will probably remove it soon.
2021-06-02 11:06:02 -07:00
Aditya Sharad
1ec2fd7ea1 Merge pull request #542 from github/robertbrignull/import-actions-lib
Update unguarded-action-lib.ql to catch uses of actions-util.ts
2021-06-02 09:56:37 -07:00
Robert
61b561867b Update unguarded-action-lib.ql 2021-06-02 16:51:30 +01:00
Andrew Eisenberg
4ac9009dfe Merge pull request #541 from github/update-supported-enterprise-server-versions
Update supported GitHub Enterprise Server versions.
2021-06-02 08:28:15 -07:00
Andrew Eisenberg
e8486b0d6c Merge branch 'main' into update-supported-enterprise-server-versions 2021-06-02 08:14:19 -07:00
Edoardo Pirovano
0cbd4b56d3 Add some dependencies for uploading artifacts 2021-06-02 10:32:48 +01:00
Andrew Eisenberg
739e14d879 Merge branch 'main' into update-supported-enterprise-server-versions 2021-06-01 22:40:01 -07:00
Andrew Eisenberg
1d05ad7576 Merge pull request #536 from github/aeisenberg/commander
Use commander preAction hook for setMode
2021-06-01 18:35:01 -07:00
GitHub
2fee1242f4 Update supported GitHub Enterprise Server versions. 2021-06-02 00:23:42 +00:00
Andrew Eisenberg
539d968ad7 Use commander preAction hook for setMode
Hooks are new to commander v8. We can use hooks to ensure that `setMode`
is called before every command is invoked.
2021-06-01 11:17:49 -07:00
Andrew Eisenberg
4b4a5ee9d1 Merge pull request #534 from github/aeisenberg/mergeback-fix
Fix the mergeback workflow
2021-06-01 10:35:47 -07:00
Andrew Eisenberg
f0e82b7d63 1.0.1 2021-05-31 10:56:52 -07:00
Andrew Eisenberg
c02d8cc7a9 Fix EOF newlines after npm version patch
The removeNPMAbsolutePaths check requires no newlines at the
end of the file. This ensures that the version update mimics
the behavior.
2021-05-31 10:37:07 -07:00
Andrew Eisenberg
a94829cc53 Manually update the CHANGELOG
This should have happened in a mergeback PR, but the workflow to
generate this was broken.
2021-05-31 10:11:08 -07:00
Andrew Eisenberg
7d701d23e3 Merge remote-tracking branch 'upstream/v1' into aeisenberg/mergeback-fix 2021-05-31 10:09:13 -07:00
Andrew Eisenberg
981b5cb012 Fix the mergeback workflow
We need to tag and mergeback if the tag does _not_ already exist.
2021-05-31 10:08:10 -07:00
Andrew Eisenberg
ca9450846f Merge pull request #516 from github/aeisenberg/user-agent
Send version and mode to code scanning via user agent
2021-05-31 09:49:44 -07:00
Andrew Eisenberg
1a4cdd35b9 Use the version from package.json in the runner 2021-05-31 09:35:13 -07:00
Andrew Eisenberg
4164096c0d Use the version from package.json in the runner
Update the ql queries to account for change in how we look for runner

Previously, we guarded blocks of code to be run by the runner or the
action using if statements like this:

```js
if (mode === "actions") ...
```

We are no longer doing this. And now, the `unguarded-action-lib.ql`
query is out of date. This query checks that runner code does not
unintentionally access actions-only methods in the libraries.

With these changes, we now ensure that code scanning is happy.
2021-05-31 09:34:41 -07:00
Andrew Eisenberg
47588796b4 Send the version and mode with the user agent
This commit changes the way the action determines if running in action
or runner mode. There is now an environment variable that is set at the
beginning of the process and elsewhere in the process, we can check to
see if the variable is set.
2021-05-31 09:03:29 -07:00
Andrew Eisenberg
fad7cc482d Merge pull request #438 from okyanusoz/patch-1
Fix wording in README
2021-05-31 09:02:45 -07:00
Andrew Eisenberg
4917d3c7e8 Merge pull request #533 from github/update-v1.0.0-ff75ec7f
Merge main into v1
2021-05-31 08:13:07 -07:00
Andrew Eisenberg
dd66f4484d Remove leading newline
Minor change.
2021-05-31 08:12:29 -07:00
github-actions[bot]
cf57db7e1f 1.0.0 2021-05-31 09:24:10 +00:00
Andrew Eisenberg
d9a17baf2f Merge branch 'main' into patch-1 2021-05-28 15:29:27 -07:00
Henry Mercer
ff75ec7f7d Merge pull request #532 from github/henrymercer/analysis-summaries-custom-queries
Analyze: Log analysis summaries for custom queries
2021-05-28 21:48:16 +01:00
Henry Mercer
1362396c57 Add changelog note 2021-05-28 20:19:55 +01:00
Henry Mercer
2338fe5db5 Analyze: Log analysis summaries for custom queries 2021-05-28 19:36:21 +01:00
Andrew Eisenberg
2ccefaccfe Merge pull request #510 from github/aeisenberg/update-changelog-on-release
Add release and mergeback workflows
2021-05-27 13:22:14 -07:00
Andrew Eisenberg
8b0110800e Merge branch 'main' into aeisenberg/update-changelog-on-release 2021-05-27 13:12:26 -07:00
Andrew Eisenberg
ea89b06c41 Add bump runner version whenever action is versioned
Ensures that the runner version is bumped along with the action version.
2021-05-27 12:31:58 -07:00
Arthur Baars
12b2dc68b9 Merge pull request #513 from github/aibaars-patch-1
Add Ruby as a possible language
2021-05-26 07:40:23 +02:00
Arthur Baars
213f5407e2 Merge branch 'main' into aibaars-patch-1 2021-05-26 07:30:01 +02:00
Aditya Sharad
f4e2dc747e Merge pull request #531 from github/adityasharad/actions/enterprise-versions-upstream-only
Actions: Run enterprise versions workflow only on the parent repo
2021-05-25 19:02:45 -07:00
Andrew Eisenberg
6764ac6d01 Merge pull request #527 from github/update-v1-eeaefb60
Merge main into v1
2021-05-25 19:00:39 -07:00
Aditya Sharad
a55e7e1f67 Actions: Run enterprise versions workflow only on the parent repo
Don't run the cron workflow on forks, since they lack the necessary secrets.
2021-05-25 17:48:14 -07:00
Arthur Baars
44c6b33642 Address comments 2021-05-24 11:00:02 +02:00
Arthur Baars
4f51b8c47e Check available languages 2021-05-23 21:14:07 +02:00
Andrew Eisenberg
800a951427 Add release and mergeback workflows
This commit ensures that the changelog is updated before a release with
the correct date and version.

Also, after a release, a mergeback PR is created to ensure that the
changelog update and version bump is available in main.
2021-05-21 11:04:38 -07:00
Arthur Baars
91700099ba Fix unit test 2021-05-21 18:45:08 +02:00
Arthur Baars
c3633dc9bd Add Ruby as a possible language 2021-05-21 18:45:08 +02:00
Henning Makholm
88f6e15932 Merge pull request #508 from github/update-v1-79c79f1b
Merge main into v1
2021-05-19 15:11:11 +02:00
Andrew Eisenberg
b393038372 Merge pull request #504 from github/update-v1-21830ef0
Merge main into v1
2021-05-17 08:44:48 -07:00
Andrew Eisenberg
e94d93ad78 Merge branch 'main' into patch-1 2021-05-17 08:30:13 -07:00
Andrew Eisenberg
4a083a45c2 Merge pull request #491 from github/update-v1-f00bafbd
Merge main into v1
2021-05-10 08:07:39 -07:00
Aditya Sharad
9a415429a9 Merge pull request #473 from github/update-v1-8e3540bb
Merge main into v1
2021-05-03 15:29:45 -07:00
Henning Makholm
6b86057d79 Merge pull request #471 from github/update-v1-cb581084
Merge main into v1
2021-04-30 19:18:44 +02:00
Andrew Eisenberg
83b730ea82 Merge pull request #461 from github/update-v1-7c5b1287
Merge main into v1
2021-04-26 09:05:53 -07:00
Henning Makholm
429ece1037 Merge pull request #455 from github/update-v1-896b4ff1
Merge main into v1
2021-04-21 20:50:55 +02:00
David Verdeguer
75dbb28e2f Merge pull request #453 from github/update-v1-1fa35632
Merge main into v1
2021-04-20 14:27:30 +02:00
Andrew Eisenberg
9db4c5714e Merge pull request #449 from github/update-v1-8bd2b351
Merge main into v1
2021-04-19 08:33:23 -07:00
Andrew Eisenberg
af641b2d26 Use externalRepoAuth when getting a remote config
This allows users to specify a different token for retrieving the
codeql config from a different repository.

Fixes https://github.com/github/advanced-security-field/issues/185
2021-04-12 08:02:30 -07:00
Aditya Sharad
8a00ebe607 Code scanning: Compare the default and latest CodeQL tools bundles
Create a prerequisite job that runs the init step twice, with `tools: null` and `tools: latest`.
Use the outputs of these steps to compare the two CodeQL versions.
Pass the list of distinct tool versions for the analysis job to matrix over.
This lets us test the analysis against both versions, while avoiding duplication
when they are actually the same version.
2021-04-12 08:02:30 -07:00
Aditya Sharad
6b4df91bd2 PR checks: Compare the default and latest CodeQL tools bundles
Create a prerequisite job that runs the init step twice, with `tools: null` and `tools: latest`.
Use the outputs of these steps to compare the two CodeQL versions.
Pass the list of distinct tool versions for the integration tests to use in their matrix strategy.
This avoids redundant test jobs when the default and latest bundles are actually the same version of CodeQL.

`~` is accepted by JSON but not by the Actions context language, so we use `null` to indicate the default version.
2021-04-12 08:02:30 -07:00
Aditya Sharad
757ff9962f PR checks: Run integration tests against both tools: null and tools: latest
Always test against both the default and latest CodeQL bundle.

This improves test coverage shortly after a CodeQL bundle release, where the latest bundle
may not yet be built into the Actions VM image as the default bundle.

It also saves a manual step during bundle release testing,
since we no longer need to temporarily change the PR checks to `tools: latest`.

There is some redundancy when the latest bundle is the same as the default bundle on the VM image,
but this can be considered a test for the `tools: latest` configuration.
2021-04-12 08:02:30 -07:00
Aditya Sharad
ed446be54b Merge pull request #439 from github/update-v1-7f9fb10a
Merge main into v1
2021-04-05 12:02:07 -07:00
okyanusoz
8a1d7c290f Fix wording in README 2021-04-03 21:55:03 +03:00
Henning Makholm
f8f120e93b Merge pull request #434 from github/update-v1-bf8daada
Merge main into v1
2021-03-26 20:18:38 +01:00
Aditya Sharad
687b7b73f7 Merge pull request #429 from github/update-v1-5d467d01
Merge main into v1
2021-03-22 07:42:13 -07:00
Chris Gavin
0ed969c530 Merge pull request #419 from github/update-v1-cfec2bbc
Merge main into v1
2021-03-15 10:22:24 +00:00
Aditya Sharad
df9359871e Merge pull request #415 from github/update-v1-2fcc4eb0
Merge main into v1
2021-03-09 11:12:08 -08:00
Aditya Sharad
5c4e11807d Merge pull request #413 from github/update-v1-6ddfab14
Merge main into v1
2021-03-08 11:35:14 -08:00
Simon Engledew
145b51c270 Merge pull request #410 from github/update-v1-bde489c6
Merge main into v1
2021-03-08 15:50:17 +00:00
Chris Gavin
e40d00393d Merge pull request #405 from github/update-v1-964ae012
Merge main into v1
2021-03-01 10:57:06 +00:00
Robert
d00607bc7b Merge pull request #399 from github/update-v1-bcd7b2de
Merge main into v1
2021-02-22 10:37:31 +00:00
Chris Gavin
21026345ae Merge pull request #388 from github/update-v1-781e3bc5
Merge main into v1
2021-02-08 11:37:49 +00:00
Robin Neatherway
0dcd795b4c Merge pull request #384 from github/update-v1-6408d722
Merge main into v1
2021-02-01 10:29:19 +00:00
Robert
3a205cc343 Merge pull request #372 from github/update-v1-7a340d32
Merge main into v1
2021-01-25 10:56:12 +00:00
Robert
ce35c1c3a5 Merge pull request #366 from github/update-v1-8659fb33
Merge main into v1
2021-01-18 10:22:40 +00:00
Robert
32a206ea17 Merge pull request #359 from github/update-v1-a0c4707d
Merge main into v1
2021-01-11 10:11:38 +00:00
Chris Gavin
bb9d573cf9 Merge pull request #354 from github/update-v1-094554cf
Merge main into v1
2021-01-04 11:10:06 +00:00
Chris Gavin
c2dc86575a Merge pull request #350 from github/prevent-accidental-analysis-of-get-pip-v1
Prevent accidental analysis of the `get-pip.py` script. [v1 cherry-pick]
2020-12-22 15:12:10 +00:00
Chris Gavin
b8f3d839cc Prevent accidental analysis of the get-pip.py script. 2020-12-22 14:36:09 +00:00
Chris Gavin
4d262138e1 Merge pull request #345 from github/update-v1-8cbc02a4
Merge main into v1
2020-12-14 11:42:02 +00:00
Robert
049e10c079 Merge pull request #338 from github/update-v1-494945f7
Merge main into v1
2020-12-07 09:51:43 +00:00
268 changed files with 18493 additions and 6867 deletions

View File

@@ -4,6 +4,17 @@ import random
import requests
import subprocess
import sys
import json
import datetime
import os
EMPTY_CHANGELOG = """# CodeQL Action and CodeQL Runner Changelog
## [UNRELEASED]
No user facing changes.
"""
# The branch being merged from.
# This is the one that contains day-to-day development work.
@@ -49,32 +60,40 @@ def open_pr(repo, all_commits, short_main_sha, branch_name):
commits_without_pull_requests = sorted(commits_without_pull_requests, key=lambda c: c.commit.author.date)
# Start constructing the body text
body = 'Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH
body = []
body.append('Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH)
conductor = get_conductor(repo, pull_requests, commits_without_pull_requests)
body += '\n\nConductor for this PR is @' + conductor
body.append('')
body.append('Conductor for this PR is @' + conductor)
# List all PRs merged
if len(pull_requests) > 0:
body += '\n\nContains the following pull requests:'
body.append('')
body.append('Contains the following pull requests:')
for pr in pull_requests:
merger = get_merger_of_pr(repo, pr)
body += '\n- #' + str(pr.number)
body += ' - ' + pr.title
body += ' (@' + merger + ')'
body.append('- #' + str(pr.number) + ' - ' + pr.title +' (@' + merger + ')')
# List all commits not part of a PR
if len(commits_without_pull_requests) > 0:
body += '\n\nContains the following commits not from a pull request:'
body.append('')
body.append('Contains the following commits not from a pull request:')
for commit in commits_without_pull_requests:
body += '\n- ' + commit.sha
body += ' - ' + get_truncated_commit_message(commit)
body += ' (@' + commit.author.login + ')'
body.append('- ' + commit.sha + ' - ' + get_truncated_commit_message(commit) + ' (@' + commit.author.login + ')')
body.append('')
body.append('Please review the following:')
body.append(' - [ ] The CHANGELOG displays the correct version and date.')
body.append(' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.')
body.append(' - [ ] There are no unexpected commits being merged into the ' + LATEST_RELEASE_BRANCH + ' branch.')
body.append(' - [ ] The docs team is aware of any documentation changes that need to be released.')
body.append(' - [ ] The mergeback PR is merged back into ' + MAIN_BRANCH + ' after this PR is merged.')
title = 'Merge ' + MAIN_BRANCH + ' into ' + LATEST_RELEASE_BRANCH
# Create the pull request
pr = repo.create_pull(title=title, body=body, head=branch_name, base=LATEST_RELEASE_BRANCH)
pr = repo.create_pull(title=title, body='\n'.join(body), head=branch_name, base=LATEST_RELEASE_BRANCH)
print('Created PR #' + str(pr.number))
# Assign the conductor
@@ -95,7 +114,7 @@ def get_conductor(repo, pull_requests, other_commits):
# This will not include any commits that exist on the release branch
# that aren't on main.
def get_commit_difference(repo):
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + MAIN_BRANCH).strip().split('\n')
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + ORIGIN + '/' + MAIN_BRANCH).strip().split('\n')
# Convert to full-fledged commit objects
commits = [repo.get_commit(c) for c in commits]
@@ -105,7 +124,7 @@ def get_commit_difference(repo):
# Is the given commit the automatic merge commit from when merging a PR
def is_pr_merge_commit(commit):
return commit.committer.login == 'web-flow' and len(commit.parents) > 1
return commit.committer is not None and commit.committer.login == 'web-flow' and len(commit.parents) > 1
# Gets a copy of the commit message that should display nicely
def get_truncated_commit_message(commit):
@@ -135,6 +154,28 @@ def get_pr_for_commit(repo, commit):
def get_merger_of_pr(repo, pr):
return repo.get_commit(pr.merge_commit_sha).author.login
def get_current_version():
with open('package.json', 'r') as f:
return json.load(f)['version']
def get_today_string():
today = datetime.datetime.today()
return '{:%d %b %Y}'.format(today)
def update_changelog(version):
if (os.path.exists('CHANGELOG.md')):
content = ''
with open('CHANGELOG.md', 'r') as f:
content = f.read()
else:
content = EMPTY_CHANGELOG
newContent = content.replace('[UNRELEASED]', version + ' - ' + get_today_string(), 1)
with open('CHANGELOG.md', 'w') as f:
f.write(newContent)
def main():
if len(sys.argv) != 3:
raise Exception('Usage: update-release.branch.py <github token> <repository nwo>')
@@ -142,10 +183,11 @@ def main():
repository_nwo = sys.argv[2]
repo = Github(github_token).get_repo(repository_nwo)
version = get_current_version()
# Print what we intend to go
print('Considering difference between ' + MAIN_BRANCH + ' and ' + LATEST_RELEASE_BRANCH)
short_main_sha = run_git('rev-parse', '--short', MAIN_BRANCH).strip()
short_main_sha = run_git('rev-parse', '--short', ORIGIN + '/' + MAIN_BRANCH).strip()
print('Current head of ' + MAIN_BRANCH + ' is ' + short_main_sha)
# See if there are any commits to merge in
@@ -157,7 +199,7 @@ def main():
# The branch name is based off of the name of branch being merged into
# and the SHA of the branch being merged from. Thus if the branch already
# exists we can assume we don't need to recreate it.
new_branch_name = 'update-' + LATEST_RELEASE_BRANCH + '-' + short_main_sha
new_branch_name = 'update-v' + version + '-' + short_main_sha
print('Branch name is ' + new_branch_name)
# Check if the branch already exists. If so we can abort as this script
@@ -168,7 +210,15 @@ def main():
# Create the new branch and push it to the remote
print('Creating branch ' + new_branch_name)
run_git('checkout', '-b', new_branch_name, MAIN_BRANCH)
run_git('checkout', '-b', new_branch_name, ORIGIN + '/' + MAIN_BRANCH)
print('Updating changelog')
update_changelog(version)
# Create a commit that updates the CHANGELOG
run_git('add', 'CHANGELOG.md')
run_git('commit', '-m', version)
run_git('push', ORIGIN, new_branch_name)
# Open a PR to update the branch

View File

@@ -0,0 +1,123 @@
# This workflow runs after a release of the action.
# It merges any changes from the release back into the
# main branch. Typically, this is just a single commit
# that updates the changelog.
name: Tag release and merge back
on:
workflow_dispatch:
inputs:
baseBranch:
description: 'The base branch to merge into'
default: main
required: false
push:
branches:
- v1
jobs:
merge-back:
runs-on: ubuntu-latest
if: github.repository == 'github/codeql-action'
env:
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'main' }}"
HEAD_BRANCH: "${{ github.head_ref || github.ref }}"
steps:
- name: Dump GitHub Event context
env:
GITHUB_EVENT_CONTEXT: "${{ toJson(github.event) }}"
run: echo "$GITHUB_EVENT_CONTEXT"
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- name: Update git config
run: |
git config --global user.email "github-actions@github.com"
git config --global user.name "github-actions[bot]"
- name: Get version and new branch
id: getVersion
run: |
VERSION="v$(jq '.version' -r 'package.json')"
SHORT_SHA="${GITHUB_SHA:0:8}"
echo "::set-output name=version::$VERSION"
NEW_BRANCH="mergeback/${VERSION}-to-${BASE_BRANCH}-${SHORT_SHA}"
echo "::set-output name=newBranch::$NEW_BRANCH"
- name: Dump branches
env:
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
run: |
echo "BASE_BRANCH $BASE_BRANCH"
echo "HEAD_BRANCH $HEAD_BRANCH"
echo "NEW_BRANCH $NEW_BRANCH"
- name: Create mergeback branch
env:
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
run: |
git checkout -b "$NEW_BRANCH"
- name: Check for tag
id: check
env:
VERSION: "${{ steps.getVersion.outputs.version }}"
run: |
set +e # don't fail on an errored command
git ls-remote --tags origin | grep "$VERSION"
EXISTS="$?"
if [ "$EXISTS" -eq 0 ]; then
echo "Tag $TAG exists. Not going to re-release."
echo "::set-output name=exists::true"
else
echo "Tag $TAG does not exist yet."
fi
# we didn't tag the release during the update-release-branch workflow because the
# commit that actually makes it to the release branch is a merge commit,
# and not yet known during the first workflow. We tag now because we know the correct commit.
- name: Tag release
if: steps.check.outputs.exists != 'true'
env:
VERSION: ${{ steps.getVersion.outputs.version }}
run: |
git tag -a "$VERSION" -m "$VERSION"
git fetch --unshallow # unshallow the repo in order to allow pushes
git push origin --follow-tags "$VERSION"
- name: Create mergeback branch
if: steps.check.outputs.exists != 'true'
env:
VERSION: "${{ steps.getVersion.outputs.version }}"
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
run: |
set -exu
PR_TITLE="Mergeback $VERSION $HEAD_BRANCH into $BASE_BRANCH"
PR_BODY="Updates version and changelog."
# Update the changelog
perl -i -pe 's/^/## \[UNRELEASED\]\n\nNo user facing changes.\n\n/ if($.==3)' CHANGELOG.md
git add .
git commit -m "Update changelog and version after $VERSION"
npm version patch
# when running this workflow on a PR, this is just a test.
# so put into draft mode.
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
DRAFT="--draft"
else
DRAFT=""
fi
git push origin "$NEW_BRANCH"
gh pr create \
--head "$NEW_BRANCH" \
--base "$BASE_BRANCH" \
--title "$PR_TITLE" \
--body "$PR_BODY" \
${DRAFT:+"$DRAFT"} # no quotes around $DRAFT. gh will error out if there is an empty ""

View File

@@ -65,22 +65,175 @@ jobs:
shell: bash
run: ./build.sh
- uses: ./../action/analyze
id: analysis
env:
TEST_MODE: true
- run: |
cd "$RUNNER_TEMP/customDbLocation"
# List all directories as there will be precisely one directory per database
# but there may be other files in this directory such as query suites.
if [ "$(ls -d */ | wc -l)" != 6 ] || \
[[ ! -d cpp ]] || \
[[ ! -d csharp ]] || \
[[ ! -d go ]] || \
[[ ! -d java ]] || \
[[ ! -d javascript ]] || \
[[ ! -d python ]]; then
echo "Did not find expected number of databases. Database dir contains: $(ls)"
CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }}
if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for CPP, or created it in the wrong location."
exit 1
fi
CSHARP_DB=${{ fromJson(steps.analysis.outputs.db-locations).csharp }}
if [[ ! -d $CSHARP_DB ]] || [[ ! $CSHARP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for C Sharp, or created it in the wrong location."
exit 1
fi
GO_DB=${{ fromJson(steps.analysis.outputs.db-locations).go }}
if [[ ! -d $GO_DB ]] || [[ ! $GO_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for Go, or created it in the wrong location."
exit 1
fi
JAVA_DB=${{ fromJson(steps.analysis.outputs.db-locations).java }}
if [[ ! -d $JAVA_DB ]] || [[ ! $JAVA_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for Java, or created it in the wrong location."
exit 1
fi
JAVASCRIPT_DB=${{ fromJson(steps.analysis.outputs.db-locations).javascript }}
if [[ ! -d $JAVASCRIPT_DB ]] || [[ ! $JAVASCRIPT_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for Javascript, or created it in the wrong location."
exit 1
fi
PYTHON_DB=${{ fromJson(steps.analysis.outputs.db-locations).python }}
if [[ ! -d $PYTHON_DB ]] || [[ ! $PYTHON_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
echo "Did not create a database for Python, or created it in the wrong location."
exit 1
fi
# Packaging test that runs against a javascript database
# Specifying packs in the config file.
test-packaging-javascript-config:
needs: [check-js, check-node-modules]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Move codeql-action
shell: bash
run: |
mkdir ../action
mv * .github ../action/
mv ../action/tests/multi-language-repo/{*,.github} .
mv ../action/.github/workflows .github
- uses: ./../action/init
with:
config-file: ".github/codeql/codeql-config-packaging.yml"
languages: javascript
# TODO: this can be removed when cli v2.5.6 is released and available in the tool cache
tools: https://github.com/dsp-testing/aeisenberg-codeql-action-packaging/releases/download/codeql-bundle-20210615/codeql-bundle-linux64.tar.gz
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
env:
TEST_MODE: true
- name: Assert Results
run: |
cd "$RUNNER_TEMP/results"
# We should have 3 hits from these rules
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
echo "Found matching rules '$RULES'"
if [ "$RULES" != "$EXPECTED_RULES" ]; then
echo "Did not match expected rules '$EXPECTED_RULES'."
exit 1
fi
# Packaging test that runs against a javascript database
# Specifying packs as an input.
test-packaging-javascript-inputs:
needs: [check-js, check-node-modules]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Move codeql-action
shell: bash
run: |
mkdir ../action
mv * .github ../action/
mv ../action/tests/multi-language-repo/{*,.github} .
mv ../action/.github/workflows .github
- uses: ./../action/init
with:
config-file: ".github/codeql/codeql-config-packaging2.yml"
languages: javascript
packs: dsp-testing/codeql-pack1@0.0.4, dsp-testing/codeql-pack2
# TODO: this can be removed when cli v2.5.6 is released and available in the tool cache
tools: https://github.com/dsp-testing/aeisenberg-codeql-action-packaging/releases/download/codeql-bundle-20210615/codeql-bundle-linux64.tar.gz
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
env:
TEST_MODE: true
- name: Assert Results
run: |
cd "$RUNNER_TEMP/results"
# We should have 3 hits from these rules
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
echo "Found matching rules '$RULES'"
if [ "$RULES" != "$EXPECTED_RULES" ]; then
echo "Did not match expected rules '$EXPECTED_RULES'."
exit 1
fi
# Packaging test that runs against a javascript database
# Specifying packs in the config file and inputs.
test-packaging-javascript-config-and-inputs:
needs: [check-js, check-node-modules]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Move codeql-action
shell: bash
run: |
mkdir ../action
mv * .github ../action/
mv ../action/tests/multi-language-repo/{*,.github} .
mv ../action/.github/workflows .github
- uses: ./../action/init
with:
config-file: ".github/codeql/codeql-config-packaging3.yml"
packs: +dsp-testing/codeql-pack1@0.0.4
languages: javascript
# TODO: this can be removed when cli v2.5.6 is released and available in the tool cache
tools: https://github.com/dsp-testing/aeisenberg-codeql-action-packaging/releases/download/codeql-bundle-20210615/codeql-bundle-linux64.tar.gz
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
output: "${{ runner.temp }}/results"
env:
TEST_MODE: true
- name: Assert Results
run: |
cd "$RUNNER_TEMP/results"
# We should have 3 hits from these rules
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
echo "Found matching rules '$RULES'"
if [ "$RULES" != "$EXPECTED_RULES" ]; then
echo "Did not match expected rules '$EXPECTED_RULES'."
exit 1
fi
# Identify the CodeQL tool versions to integration test against.
check-codeql-versions:

View File

@@ -14,7 +14,7 @@ npm run removeNPMAbsolutePaths
# Check that repo is still clean
if [ ! -z "$(git status --porcelain)" ]; then
# If we get a fail here then the PR needs attention
>&2 echo "Failed: node_modules are not up to date. Run 'npm ci' and 'npm run removeNPMAbsolutePaths' to update"
>&2 echo "Failed: node_modules are not up to date. Run 'npm ci && npm run removeNPMAbsolutePaths' on a macOS machine to update. Note it is important this command is run on macOS and not any other operating system as there is one dependency (fsevents) that is needed for macOS and may not be installed if the command is run on a Windows or Linux machine."
git status
exit 1
fi

View File

@@ -22,12 +22,17 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.5
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install PyGithub==1.51 requests
- name: Update git config
run: |
git config --global user.email "github-actions@github.com"
git config --global user.name "github-actions[bot]"
- name: Update release branch
run: python .github/update-release-branch.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }}

View File

@@ -7,6 +7,7 @@ on:
jobs:
update-supported-enterprise-server-versions:
runs-on: ubuntu-latest
if: ${{ github.repository == 'github/codeql-action' }}
steps:
- name: Setup Python

View File

@@ -2,5 +2,30 @@
## [UNRELEASED]
No user facing changes.
## 1.0.4 - 28 Jun 2021
- Fix `RUNNER_TEMP environment variable must be set` when using runner. [#594](https://github.com/github/codeql-action/pull/594)
- Fix couting of lines of code for C# projects. [#586](https://github.com/github/codeql-action/pull/586)
## 1.0.3 - 23 Jun 2021
No user facing changes.
## 1.0.2 - 17 Jun 2021
- Fix out of memory in hash computation. [#550](https://github.com/github/codeql-action/pull/550)
- Clean up logging during analyze results. [#557](https://github.com/github/codeql-action/pull/557)
- Add `--finalize-dataset` to `database finalize` call, freeing up some disk space after database creation. [#558](https://github.com/github/codeql-action/pull/558)
## 1.0.1 - 07 Jun 2021
- Pass the `--sarif-group-rules-by-pack` argument to CodeQL CLI invocations that generate SARIF. This means the SARIF rule object for each query will now be found underneath its corresponding query pack in `runs[].tool.extensions`. [#546](https://github.com/github/codeql-action/pull/546)
- Output the location of CodeQL databases created in the analyze step. [#543](https://github.com/github/codeql-action/pull/543)
## 1.0.0 - 31 May 2021
- Add this changelog file. [#507](https://github.com/github/codeql-action/pull/507)
- Improve grouping of analysis logs. Add a new log group containing a summary of metrics and diagnostics, if they were produced by CodeQL builtin queries. [#515](https://github.com/github/codeql-action/pull/515)
- Improve grouping of analysis logs. Add a new log group containing a summary of metrics and diagnostics, if they were produced by CodeQL builtin queries. [#515](https://github.com/github/codeql-action/pull/515)
- Add metrics and diagnostics summaries from custom query suites to the analysis summary log group. [#532](https://github.com/github/codeql-action/pull/532)

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
**/* @github/codeql-action-reviewers

View File

@@ -12,7 +12,7 @@ Please note that this project is released with a [Contributor Code of Conduct][c
## Development and Testing
Before you start, ensure that you have a recent version of node installed. You can see which version of node is used by the action in `init/action.yml`.
Before you start, ensure that you have a recent version of node (14 or higher) installed, along with a recent version of npm (7 or higher). You can see which version of node is used by the action in `init/action.yml`.
### Common tasks
@@ -28,32 +28,12 @@ You may want to run `tsc --watch` from the command line or inside of vscode in o
Because CodeQL Action users consume the code directly from this repository, and there can be no build step during an GitHub Actions run, this repository contains all compiled artifacts and node modules. There is a PR check that will fail if any of the compiled artifacts are not up to date. Compiled artifacts are stored in the `lib/` directory. For all day-to-day development purposes, this folder can be ignored.
Only run `npm install` if you are explicitly changing the set of dependencies in `package.json`. The `node_modules` directory should be up to date when you check out, but if for some reason, there is an inconsistency use `npm ci && npm run removeNPMAbsolutePaths` to ensure the directory is in a state consistent with the `package-lock.json`. There is a PR check to ensure the consistency of the `node_modules` directory.
Only run `npm install` if you are explicitly changing the set of dependencies in `package.json`. The `node_modules` directory should be up to date when you check out, but if for some reason, there is an inconsistency use `npm ci && npm run removeNPMAbsolutePaths` to ensure the directory is in a state consistent with the `package-lock.json`. Note that due to a macOS-specific dependency, this command should be run on a macOS machine. There is a PR check to ensure the consistency of the `node_modules` directory.
### Running the action
To see the effect of your changes and to test them, push your changes in a branch and then look at the [Actions output](https://github.com/github/codeql-action/actions) for that branch. You can also exercise the code locally by running the automated tests.
### Running the action locally
It is possible to run this action locally via [act](https://github.com/nektos/act) via the following steps:
1. Create a GitHub [Personal Access Token](https://github.com/settings/tokens) (PAT).
1. Install [act](https://github.com/nektos/act) v0.2.10 or greater.
1. Add a `.env` file in the root of the project you are running:
```bash
CODEQL_LOCAL_RUN=true
GITHUB_SERVER_URL=https://github.com
# Optional, for better logging
GITHUB_JOB=<ANY_JOB_NAME>
```
1. Run `act -j codeql -s GITHUB_TOKEN=<PAT>`
Running locally will generate the CodeQL database and run all the queries, but it will avoid uploading and reporting results to GitHub. Note that this must be done on a repository that _consumes_ this action, not this repository. The use case is to debug failures of this action on specific repositories.
### Integration tests
As well as the unit tests (see _Common tasks_ above), there are integration tests, defined in `.github/workflows/integration-testing.yml`. These are run by a CI check. Depending on the change youre making, you may want to add a test to this file or extend an existing one.

View File

@@ -1,6 +1,6 @@
# CodeQL Action
This action runs GitHub's industry-leading static analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
This action runs GitHub's industry-leading semantic code analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
For a list of recent changes, see the CodeQL Action's [changelog](CHANGELOG.md).
@@ -128,3 +128,11 @@ By default, this will override any queries specified in a config file. If you wi
## Troubleshooting
Read about [troubleshooting code scanning](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning).
### Note on "missing analysis" message
The very first time code scanning is run and if it is on a pull request, you will probably get a message mentioning a "missing analysis". This is expected.
After code scanning has analyzed the code in a pull request, it needs to compare the analysis of the topic branch (the merge commit of the branch you used to create the pull request) with the analysis of the base branch (the branch into which you want to merge the pull request). This allows code scanning to compute which alerts are newly introduced by the pull request, which alerts were already present in the base branch, and whether any existing alerts are fixed by the changes in the pull request. Initially, if you use a pull request to add code scanning to a repository, the base branch has not yet been analyzed, so it's not possible to compute these details. In this case, when you click through from the results check on the pull request you will see the "Missing analysis for base commit SHA-HASH" message.
For more information and other causes of this message, see [Reasons for the "missing analysis" message](https://docs.github.com/en/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/setting-up-code-scanning-for-a-repository#reasons-for-the-missing-analysis-message)

View File

@@ -13,6 +13,10 @@ inputs:
description: Upload the SARIF file
required: false
default: "true"
cleanup-level:
description: "Level of cleanup to perform on CodeQL databases at the end of the analyze step. This should either be 'none' to skip cleanup, or be a valid argument for the --mode flag of the CodeQL CLI command 'codeql database cleanup' as documented at https://codeql.github.com/docs/codeql-cli/manual/database-cleanup"
required: false
default: "brutal"
ram:
description: Override the amount of memory in MB to be used by CodeQL. By default, almost all the memory of the machine is used.
required: false
@@ -30,10 +34,17 @@ inputs:
category:
description: String used by Code Scanning for matching the analyses
required: false
upload-database:
description: Whether to upload the resulting CodeQL database
required: false
default: "true"
token:
default: ${{ github.token }}
matrix:
default: ${{ toJson(matrix) }}
outputs:
db-locations:
description: A map from language to absolute path for each database created by CodeQL.
runs:
using: 'node12'
main: '../lib/analyze-action.js'

View File

@@ -22,6 +22,15 @@ inputs:
queries:
description: Comma-separated list of additional queries to run. By default, this overrides the same setting in a configuration file; prefix with "+" to use both sets of queries.
required: false
packs:
description: >-
[Experimental] Comma-separated list of packs to run. Reference a pack in the format `scope/name[@version]`. If `version` is not
specified, then the latest version of the pack is used. By default, this overrides the same setting in a
configuration file; prefix with "+" to use both sets of packs.
This input is only available in single-language analyses. To use packs in multi-language
analyses, you must specify packs in the codeql-config.yml file.
required: false
external-repository-token:
description: A token for fetching external config files and queries if they reside in a private repository.
required: false

95
lib/actions-util.js generated
View File

@@ -16,6 +16,10 @@ const yaml = __importStar(require("js-yaml"));
const api = __importStar(require("./api-client"));
const sharedEnv = __importStar(require("./shared-environment"));
const util_1 = require("./util");
/**
* The utils in this module are meant to be run inside of the action only.
* Code paths from the runner should not enter this module.
*/
/**
* Wrapper around core.getInput for inputs that always have a value.
* Also see getOptionalInput.
@@ -39,48 +43,20 @@ function getOptionalInput(name) {
return value.length > 0 ? value : undefined;
}
exports.getOptionalInput = getOptionalInput;
/**
* Get an environment parameter, but throw an error if it is not set.
*/
function getRequiredEnvParam(paramName) {
const value = process.env[paramName];
if (value === undefined || value.length === 0) {
throw new Error(`${paramName} environment variable must be set`);
}
core.debug(`${paramName}=${value}`);
return value;
}
exports.getRequiredEnvParam = getRequiredEnvParam;
function getTemporaryDirectory() {
const value = process.env["CODEQL_ACTION_TEMP"];
return value !== undefined && value !== ""
? value
: getRequiredEnvParam("RUNNER_TEMP");
: util_1.getRequiredEnvParam("RUNNER_TEMP");
}
exports.getTemporaryDirectory = getTemporaryDirectory;
function getToolCacheDirectory() {
const value = process.env["CODEQL_ACTION_TOOL_CACHE"];
return value !== undefined && value !== ""
? value
: getRequiredEnvParam("RUNNER_TOOL_CACHE");
: util_1.getRequiredEnvParam("RUNNER_TOOL_CACHE");
}
exports.getToolCacheDirectory = getToolCacheDirectory;
/**
* Ensures all required environment variables are set in the context of a local run.
*/
function prepareLocalRunEnvironment() {
if (!util_1.isLocalRun()) {
return;
}
core.debug("Action is running locally.");
if (!process.env.GITHUB_JOB) {
core.exportVariable("GITHUB_JOB", "UNKNOWN-JOB");
}
if (!process.env.CODEQL_ACTION_ANALYSIS_KEY) {
core.exportVariable("CODEQL_ACTION_ANALYSIS_KEY", `LOCAL-RUN:${process.env.GITHUB_JOB}`);
}
}
exports.prepareLocalRunEnvironment = prepareLocalRunEnvironment;
/**
* Gets the SHA of the commit that is currently checked out.
*/
@@ -109,7 +85,7 @@ exports.getCommitOid = async function (ref = "HEAD") {
}
catch (e) {
core.info(`Failed to call git to get current commit. Continuing with data from environment: ${e}`);
return getRequiredEnvParam("GITHUB_SHA");
return util_1.getRequiredEnvParam("GITHUB_SHA");
}
};
function isObject(o) {
@@ -298,7 +274,7 @@ function formatWorkflowCause(errors) {
exports.formatWorkflowCause = formatWorkflowCause;
async function getWorkflow() {
const relativePath = await getWorkflowPath();
const absolutePath = path.join(getRequiredEnvParam("GITHUB_WORKSPACE"), relativePath);
const absolutePath = path.join(util_1.getRequiredEnvParam("GITHUB_WORKSPACE"), relativePath);
return yaml.safeLoad(fs.readFileSync(absolutePath, "utf-8"));
}
exports.getWorkflow = getWorkflow;
@@ -306,13 +282,10 @@ exports.getWorkflow = getWorkflow;
* Get the path of the currently executing workflow.
*/
async function getWorkflowPath() {
if (util_1.isLocalRun()) {
return getRequiredEnvParam("WORKFLOW_PATH");
}
const repo_nwo = getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
const repo_nwo = util_1.getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
const owner = repo_nwo[0];
const repo = repo_nwo[1];
const run_id = Number(getRequiredEnvParam("GITHUB_RUN_ID"));
const run_id = Number(util_1.getRequiredEnvParam("GITHUB_RUN_ID"));
const apiClient = api.getActionsApiClient();
const runsResponse = await apiClient.request("GET /repos/:owner/:repo/actions/runs/:run_id", {
owner,
@@ -327,7 +300,7 @@ async function getWorkflowPath() {
* Get the workflow run ID.
*/
function getWorkflowRunID() {
const workflowRunID = parseInt(getRequiredEnvParam("GITHUB_RUN_ID"), 10);
const workflowRunID = parseInt(util_1.getRequiredEnvParam("GITHUB_RUN_ID"), 10);
if (Number.isNaN(workflowRunID)) {
throw new Error("GITHUB_RUN_ID must define a non NaN workflow run ID");
}
@@ -348,7 +321,7 @@ async function getAnalysisKey() {
return analysisKey;
}
const workflowPath = await getWorkflowPath();
const jobName = getRequiredEnvParam("GITHUB_JOB");
const jobName = util_1.getRequiredEnvParam("GITHUB_JOB");
analysisKey = `${workflowPath}:${jobName}`;
core.exportVariable(analysisKeyEnvVar, analysisKey);
return analysisKey;
@@ -385,8 +358,8 @@ exports.computeAutomationID = computeAutomationID;
async function getRef() {
// Will be in the form "refs/heads/master" on a push event
// or in the form "refs/pull/N/merge" on a pull_request event
const ref = getRequiredEnvParam("GITHUB_REF");
const sha = getRequiredEnvParam("GITHUB_SHA");
const ref = util_1.getRequiredEnvParam("GITHUB_REF");
const sha = util_1.getRequiredEnvParam("GITHUB_SHA");
// For pull request refs we want to detect whether the workflow
// has run `git checkout HEAD^2` to analyze the 'head' ref rather
// than the 'merge' ref. If so, we want to convert the ref that
@@ -475,10 +448,6 @@ async function createStatusReportBase(actionName, status, actionStartedAt, cause
return statusReport;
}
exports.createStatusReportBase = createStatusReportBase;
function isHTTPError(arg) {
var _a;
return ((_a = arg) === null || _a === void 0 ? void 0 : _a.status) !== undefined && Number.isInteger(arg.status);
}
const GENERIC_403_MSG = "The repo on which this action is running is not opted-in to CodeQL code scanning.";
const GENERIC_404_MSG = "Not authorized to used the CodeQL code scanning feature on this repo.";
const OUT_OF_DATE_MSG = "CodeQL Action is out-of-date. Please upgrade to the latest version of codeql-action.";
@@ -493,13 +462,9 @@ const INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the code sc
* Returns whether sending the status report was successful of not.
*/
async function sendStatusReport(statusReport) {
if (util_1.isLocalRun()) {
core.debug("Not sending status report because this is a local run");
return true;
}
const statusReportJSON = JSON.stringify(statusReport);
core.debug(`Sending status report: ${statusReportJSON}`);
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
const nwo = util_1.getRequiredEnvParam("GITHUB_REPOSITORY");
const [owner, repo] = nwo.split("/");
const client = api.getActionsApiClient();
try {
@@ -512,7 +477,7 @@ async function sendStatusReport(statusReport) {
}
catch (e) {
console.log(e);
if (isHTTPError(e)) {
if (util_1.isHTTPError(e)) {
switch (e.status) {
case 403:
if (workflowIsTriggeredByPushEvent() && isDependabotActor()) {
@@ -532,7 +497,7 @@ async function sendStatusReport(statusReport) {
// schema incompatibility when reporting status
// this means that this action version is no longer compatible with the API
// we still want to continue as it is likely the analysis endpoint will work
if (getRequiredEnvParam("GITHUB_SERVER_URL") !== util_1.GITHUB_DOTCOM_URL) {
if (util_1.getRequiredEnvParam("GITHUB_SERVER_URL") !== util_1.GITHUB_DOTCOM_URL) {
core.debug(INCOMPATIBLE_MSG);
}
else {
@@ -566,9 +531,33 @@ exports.isRunningLocalAction = isRunningLocalAction;
// Get the location where the action is running from.
// This can be used to get the actions name or tell if we're running a local action.
function getRelativeScriptPath() {
const runnerTemp = getRequiredEnvParam("RUNNER_TEMP");
const runnerTemp = util_1.getRequiredEnvParam("RUNNER_TEMP");
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
return path.relative(actionsDirectory, __filename);
}
exports.getRelativeScriptPath = getRelativeScriptPath;
// Reads the contents of GITHUB_EVENT_PATH as a JSON object
function getWorkflowEvent() {
const eventJsonFile = util_1.getRequiredEnvParam("GITHUB_EVENT_PATH");
try {
return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8"));
}
catch (e) {
throw new Error(`Unable to read workflow event JSON from ${eventJsonFile}: ${e}`);
}
}
// Is the version of the repository we are currently analyzing from the default branch,
// or alternatively from another branch or a pull request.
async function isAnalyzingDefaultBranch() {
var _a, _b;
// Get the current ref and trim and refs/heads/ prefix
let currentRef = await getRef();
currentRef = currentRef.startsWith("refs/heads/")
? currentRef.substr("refs/heads/".length)
: currentRef;
const event = getWorkflowEvent();
const defaultBranch = (_b = (_a = event) === null || _a === void 0 ? void 0 : _a.repository) === null || _b === void 0 ? void 0 : _b.default_branch;
return currentRef === defaultBranch;
}
exports.isAnalyzingDefaultBranch = isAnalyzingDefaultBranch;
//# sourceMappingURL=actions-util.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,4 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
@@ -9,12 +6,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ava_1 = __importDefault(require("ava"));
const yaml = __importStar(require("js-yaml"));
const sinon_1 = __importDefault(require("sinon"));
const actionsutil = __importStar(require("./actions-util"));
const testing_utils_1 = require("./testing-utils");
const util_1 = require("./util");
function errorCodes(actual, expected) {
return [actual.map(({ code }) => code), expected.map(({ code }) => code)];
}
@@ -56,14 +59,6 @@ ava_1.default("getRef() returns head PR ref if GITHUB_REF no longer checked out"
t.deepEqual(actualRef, "refs/pull/1/head");
callback.restore();
});
ava_1.default("getAnalysisKey() when a local run", async (t) => {
process.env.CODEQL_LOCAL_RUN = "true";
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
process.env.GITHUB_JOB = "";
actionsutil.prepareLocalRunEnvironment();
const actualAnalysisKey = await actionsutil.getAnalysisKey();
t.deepEqual(actualAnalysisKey, "LOCAL-RUN:UNKNOWN-JOB");
});
ava_1.default("computeAutomationID()", async (t) => {
let actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", '{"language": "javascript", "os": "linux"}');
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/");
@@ -80,31 +75,6 @@ ava_1.default("computeAutomationID()", async (t) => {
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", undefined);
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/");
});
ava_1.default("prepareEnvironment() when a local run", (t) => {
process.env.CODEQL_LOCAL_RUN = "false";
process.env.GITHUB_JOB = "YYY";
process.env.CODEQL_ACTION_ANALYSIS_KEY = "TEST";
actionsutil.prepareLocalRunEnvironment();
// unchanged
t.deepEqual(process.env.GITHUB_JOB, "YYY");
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "TEST");
process.env.CODEQL_LOCAL_RUN = "true";
actionsutil.prepareLocalRunEnvironment();
// unchanged
t.deepEqual(process.env.GITHUB_JOB, "YYY");
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "TEST");
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
actionsutil.prepareLocalRunEnvironment();
// updated
t.deepEqual(process.env.GITHUB_JOB, "YYY");
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "LOCAL-RUN:YYY");
process.env.GITHUB_JOB = "";
process.env.CODEQL_ACTION_ANALYSIS_KEY = "";
actionsutil.prepareLocalRunEnvironment();
// updated
t.deepEqual(process.env.GITHUB_JOB, "UNKNOWN-JOB");
t.deepEqual(process.env.CODEQL_ACTION_ANALYSIS_KEY, "LOCAL-RUN:UNKNOWN-JOB");
});
ava_1.default("getWorkflowErrors() when on is empty", (t) => {
const errors = actionsutil.getWorkflowErrors({ on: {} });
t.deepEqual(...errorCodes(errors, []));
@@ -432,4 +402,30 @@ name: "CodeQL"
on: ["push"]
`)), []));
});
ava_1.default("initializeEnvironment", (t) => {
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
t.deepEqual(util_1.getMode(), util_1.Mode.actions);
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "1.2.3");
util_1.initializeEnvironment(util_1.Mode.runner, "4.5.6");
t.deepEqual(util_1.getMode(), util_1.Mode.runner);
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "4.5.6");
});
ava_1.default("isAnalyzingDefaultBranch()", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
const envFile = path.join(tmpDir, "event.json");
fs.writeFileSync(envFile, JSON.stringify({
repository: {
default_branch: "main",
},
}));
process.env["GITHUB_EVENT_PATH"] = envFile;
process.env["GITHUB_REF"] = "main";
process.env["GITHUB_SHA"] = "1234";
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), true);
process.env["GITHUB_REF"] = "refs/heads/main";
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), true);
process.env["GITHUB_REF"] = "feature";
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), false);
});
});
//# sourceMappingURL=actions-util.test.js.map

File diff suppressed because one or more lines are too long

2
lib/analysis-paths.js generated
View File

@@ -9,7 +9,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("path"));
function isInterpretedLanguage(language) {
return language === "javascript" || language === "python";
return (language === "javascript" || language === "python" || language === "ruby");
}
// Matches a string containing only characters that are legal to include in paths on windows.
exports.legalWindowsPathCharactersRegex = /^[^<>:"|?]*$/;

View File

@@ -1 +1 @@
{"version":3,"file":"analysis-paths.js","sourceRoot":"","sources":["../src/analysis-paths.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"analysis-paths.js","sourceRoot":"","sources":["../src/analysis-paths.ts"],"names":[],"mappings":"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"}

View File

@@ -29,6 +29,7 @@ ava_1.default("emptyPaths", async (t) => {
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
dbLocation: path.resolve(tmpDir, "codeql_databases"),
packs: {},
};
analysisPaths.includeAndExcludeAnalysisPaths(config);
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
@@ -49,6 +50,7 @@ ava_1.default("nonEmptyPaths", async (t) => {
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
dbLocation: path.resolve(tmpDir, "codeql_databases"),
packs: {},
};
analysisPaths.includeAndExcludeAnalysisPaths(config);
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
@@ -70,6 +72,7 @@ ava_1.default("exclude temp dir", async (t) => {
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
dbLocation: path.resolve(tempDir, "codeql_databases"),
packs: {},
};
analysisPaths.includeAndExcludeAnalysisPaths(config);
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);

View File

@@ -1 +1 @@
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA6B;AAE7B,8CAAuB;AAEvB,gEAAkD;AAClD,mDAA6C;AAC7C,6CAA+B;AAE/B,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,aAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YAC3C,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO;YACP,YAAY;YACZ,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC;YACrD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9D,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

18
lib/analyze-action.js generated
View File

@@ -13,9 +13,13 @@ const core = __importStar(require("@actions/core"));
const actionsUtil = __importStar(require("./actions-util"));
const analyze_1 = require("./analyze");
const config_utils_1 = require("./config-utils");
const database_upload_1 = require("./database-upload");
const logging_1 = require("./logging");
const repository_1 = require("./repository");
const upload_lib = __importStar(require("./upload-lib"));
const util = __importStar(require("./util"));
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
async function sendStatusReport(startedAt, stats, error) {
var _a, _b, _c;
const status = ((_a = stats) === null || _a === void 0 ? void 0 : _a.analyze_failure_language) !== undefined || error !== undefined
@@ -32,8 +36,8 @@ async function run() {
const startedAt = new Date();
let stats = undefined;
let config = undefined;
util.initializeEnvironment(util.Mode.actions, pkg.version);
try {
actionsUtil.prepareLocalRunEnvironment();
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("finish", "starting", startedAt)))) {
return;
}
@@ -44,10 +48,18 @@ async function run() {
}
const apiDetails = {
auth: actionsUtil.getRequiredInput("token"),
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
url: util.getRequiredEnvParam("GITHUB_SERVER_URL"),
};
const outputDir = actionsUtil.getRequiredInput("output");
const queriesStats = await analyze_1.runAnalyze(outputDir, util.getMemoryFlag(actionsUtil.getOptionalInput("ram")), util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")), util.getThreadsFlag(actionsUtil.getOptionalInput("threads"), logger), actionsUtil.getOptionalInput("category"), config, logger);
if (actionsUtil.getOptionalInput("cleanup-level") !== "none") {
await analyze_1.runCleanup(config, actionsUtil.getOptionalInput("cleanup-level") || "brutal", logger);
}
const dbLocations = {};
for (const language of config.languages) {
dbLocations[language] = util.getCodeQLDatabasePath(config, language);
}
core.setOutput("db-locations", dbLocations);
if (actionsUtil.getRequiredInput("upload") === "true") {
const uploadStats = await upload_lib.uploadFromActions(outputDir, config.gitHubVersion, apiDetails, logger);
stats = { ...queriesStats, ...uploadStats };
@@ -56,6 +68,8 @@ async function run() {
logger.info("Not uploading results");
stats = { ...queriesStats };
}
const repositoryNwo = repository_1.parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY"));
await database_upload_1.uploadDatabases(repositoryNwo, config, apiDetails, logger);
}
catch (error) {
core.setFailed(error.message);

View File

@@ -1 +1 @@
{"version":3,"file":"analyze-action.js","sourceRoot":"","sources":["../src/analyze-action.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"analyze-action.js","sourceRoot":"","sources":["../src/analyze-action.ts"],"names":[],"mappings":"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"}

110
lib/analyze.js generated
View File

@@ -15,7 +15,6 @@ const codeql_1 = require("./codeql");
const count_loc_1 = require("./count-loc");
const languages_1 = require("./languages");
const sharedEnv = __importStar(require("./shared-environment"));
const upload_lib_1 = require("./upload-lib");
const util = __importStar(require("./util"));
class CodeQLAnalysisError extends Error {
constructor(queriesStatusReport, message) {
@@ -77,6 +76,7 @@ async function finalizeDatabaseCreation(config, threadsFlag, logger) {
}
// Runs queries and creates sarif files in the given folder
async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId, config, logger) {
var _a, _b;
const statusReport = {};
// count the number of lines in the background
const locPromise = count_loc_1.countLoc(path.resolve(),
@@ -85,81 +85,123 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
// that here.
config.paths, config.pathsIgnore, config.languages, logger);
for (const language of config.languages) {
logger.startGroup(`Analyzing ${language}`);
const queries = config.queries[language];
if (queries === undefined ||
(queries.builtin.length === 0 && queries.custom.length === 0)) {
const packsWithVersion = config.packs[language] || [];
const hasBuiltinQueries = ((_a = queries) === null || _a === void 0 ? void 0 : _a.builtin.length) > 0;
const hasCustomQueries = ((_b = queries) === null || _b === void 0 ? void 0 : _b.custom.length) > 0;
const hasPackWithCustomQueries = packsWithVersion.length > 0;
if (!hasBuiltinQueries && !hasCustomQueries && !hasPackWithCustomQueries) {
throw new Error(`Unable to analyse ${language} as no queries were selected for this language`);
}
try {
let analysisSummary = "";
if (hasPackWithCustomQueries) {
logger.info("*************");
logger.info("Performing analysis with custom QL Packs. QL Packs are an experimental feature.");
logger.info("And should not be used in production yet.");
logger.info("*************");
logger.startGroup(`Downloading custom packs for ${language}`);
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
const results = await codeql.packDownload(packsWithVersion);
logger.info(`Downloaded packs: ${results.packs
.map((r) => `${r.name}@${r.version || "latest"}`)
.join(", ")}`);
logger.endGroup();
}
logger.startGroup(`Running queries for ${language}`);
const querySuitePaths = [];
if (queries["builtin"].length > 0) {
const startTimeBuliltIn = new Date().getTime();
const { sarifFile, stdout } = await runQueryGroup(language, "builtin", queries["builtin"], sarifFolder, undefined);
analysisSummary = stdout;
await injectLinesOfCode(sarifFile, language, locPromise);
const startTimeBuiltIn = new Date().getTime();
querySuitePaths.push(await runQueryGroup(language, "builtin", createQuerySuiteContents(queries["builtin"]), undefined));
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
new Date().getTime() - startTimeBuliltIn;
new Date().getTime() - startTimeBuiltIn;
}
const startTimeCustom = new Date().getTime();
const temporarySarifDir = config.tempDir;
const temporarySarifFiles = [];
let ranCustom = false;
for (let i = 0; i < queries["custom"].length; ++i) {
if (queries["custom"][i].queries.length > 0) {
const { sarifFile } = await runQueryGroup(language, `custom-${i}`, queries["custom"][i].queries, temporarySarifDir, queries["custom"][i].searchPath);
temporarySarifFiles.push(sarifFile);
querySuitePaths.push(await runQueryGroup(language, `custom-${i}`, createQuerySuiteContents(queries["custom"][i].queries), queries["custom"][i].searchPath));
ranCustom = true;
}
}
if (temporarySarifFiles.length > 0) {
const sarifFile = path.join(sarifFolder, `${language}-custom.sarif`);
fs.writeFileSync(sarifFile, upload_lib_1.combineSarifFiles(temporarySarifFiles));
await injectLinesOfCode(sarifFile, language, locPromise);
if (packsWithVersion.length > 0) {
querySuitePaths.push(await runQueryGroup(language, "packs", createPackSuiteContents(packsWithVersion), undefined));
ranCustom = true;
}
if (ranCustom) {
statusReport[`analyze_custom_queries_${language}_duration_ms`] =
new Date().getTime() - startTimeCustom;
}
logger.endGroup();
// Print the LoC baseline and the summary results from database analyze.
logger.startGroup(`Analysis summary for ${language}`);
printLinesOfCodeSummary(logger, language, await locPromise);
logger.info(analysisSummary);
logger.startGroup(`Interpreting results for ${language}`);
const startTimeInterpretResults = new Date().getTime();
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
const analysisSummary = await runInterpretResults(language, querySuitePaths, sarifFile);
await injectLinesOfCode(sarifFile, language, locPromise);
statusReport[`interpret_results_${language}_duration_ms`] =
new Date().getTime() - startTimeInterpretResults;
logger.endGroup();
logger.info(analysisSummary);
printLinesOfCodeSummary(logger, language, await locPromise);
}
catch (e) {
logger.info(e);
logger.info(e.stack);
statusReport.analyze_failure_language = language;
throw new CodeQLAnalysisError(statusReport, `Error running analysis for ${language}: ${e}`);
}
}
return statusReport;
async function runQueryGroup(language, type, queries, destinationFolder, searchPath) {
async function runInterpretResults(language, queries, sarifFile) {
const databasePath = util.getCodeQLDatabasePath(config, language);
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
return await codeql.databaseInterpretResults(databasePath, queries, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId);
}
async function runQueryGroup(language, type, querySuiteContents, searchPath) {
const databasePath = util.getCodeQLDatabasePath(config, language);
// Pass the queries to codeql using a file instead of using the command
// line to avoid command line length restrictions, particularly on windows.
const querySuitePath = `${databasePath}-queries-${type}.qls`;
const querySuiteContents = queries
.map((q) => `- query: ${q}`)
.join("\n");
fs.writeFileSync(querySuitePath, querySuiteContents);
logger.debug(`Query suite file for ${language}...\n${querySuiteContents}`);
const sarifFile = path.join(destinationFolder, `${language}-${type}.sarif`);
logger.debug(`Query suite file for ${language}-${type}...\n${querySuiteContents}`);
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
const databaseAnalyzeStdout = await codeql.databaseAnalyze(databasePath, sarifFile, searchPath, querySuitePath, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId);
logger.debug(`SARIF results for database ${language} created at "${sarifFile}"`);
return { sarifFile, stdout: databaseAnalyzeStdout };
await codeql.databaseRunQueries(databasePath, searchPath, querySuitePath, memoryFlag, threadsFlag);
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
return querySuitePath;
}
}
exports.runQueries = runQueries;
function createQuerySuiteContents(queries) {
return queries.map((q) => `- query: ${q}`).join("\n");
}
function createPackSuiteContents(packsWithVersion) {
return packsWithVersion.map(packWithVersionToQuerySuiteEntry).join("\n");
}
function packWithVersionToQuerySuiteEntry(pack) {
let text = `- qlpack: ${pack.packName}`;
if (pack.version) {
text += `\n version: ${pack.version}`;
}
return text;
}
async function runAnalyze(outputDir, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId, config, logger) {
// Delete the tracer config env var to avoid tracing ourselves
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
fs.mkdirSync(outputDir, { recursive: true });
logger.info("Finalizing database creation");
await finalizeDatabaseCreation(config, threadsFlag, logger);
logger.info("Analyzing database");
const queriesStats = await runQueries(outputDir, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId, config, logger);
return { ...queriesStats };
}
exports.runAnalyze = runAnalyze;
async function runCleanup(config, cleanupLevel, logger) {
logger.startGroup("Cleaning up databases");
for (const language of config.languages) {
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
const databasePath = util.getCodeQLDatabasePath(config, language);
await codeql.databaseCleanup(databasePath, cleanupLevel);
}
logger.endGroup();
}
exports.runCleanup = runCleanup;
async function injectLinesOfCode(sarifFile, language, locPromise) {
const lineCounts = await locPromise;
const idPrefix = count_loc_1.getIdPrefix(language);
@@ -184,7 +226,7 @@ async function injectLinesOfCode(sarifFile, language, locPromise) {
}
function printLinesOfCodeSummary(logger, language, lineCounts) {
if (language in lineCounts) {
logger.info(`Counted ${lineCounts[language]} lines of code for ${language} as a baseline.`);
logger.info(`Counted a baseline of ${lineCounts[language]} lines of code for ${language}.`);
}
}
//# sourceMappingURL=analyze.js.map

File diff suppressed because one or more lines are too long

96
lib/analyze.test.js generated
View File

@@ -13,6 +13,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ava_1 = __importDefault(require("ava"));
const yaml = __importStar(require("js-yaml"));
const semver_1 = require("semver");
const sinon_1 = __importDefault(require("sinon"));
const analyze_1 = require("./analyze");
const codeql_1 = require("./codeql");
@@ -39,9 +41,27 @@ ava_1.default("status report fields and search path setting", async (t) => {
const memoryFlag = "";
const addSnippetsFlag = "";
const threadsFlag = "";
const packs = {
[languages_1.Language.cpp]: [
{
packName: "a/b",
version: semver_1.clean("1.0.0"),
},
],
[languages_1.Language.java]: [
{
packName: "c/d",
version: semver_1.clean("2.0.0"),
},
],
};
for (const language of Object.values(languages_1.Language)) {
codeql_1.setCodeQL({
databaseAnalyze: async (_, sarifFile, searchPath) => {
packDownload: async () => ({ packs: [] }),
databaseRunQueries: async (_db, searchPath) => {
searchPathsUsed.push(searchPath);
},
databaseInterpretResults: async (_db, _queriesRun, sarifFile) => {
fs.writeFileSync(sarifFile, JSON.stringify({
runs: [
// variant 1 uses ruleId
@@ -71,7 +91,6 @@ ava_1.default("status report fields and search path setting", async (t) => {
{},
],
}));
searchPathsUsed.push(searchPath);
return "";
},
});
@@ -89,6 +108,7 @@ ava_1.default("status report fields and search path setting", async (t) => {
type: util.GitHubVariant.DOTCOM,
},
dbLocation: path.resolve(tmpDir, "codeql_databases"),
packs,
};
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
recursive: true,
@@ -98,8 +118,18 @@ ava_1.default("status report fields and search path setting", async (t) => {
custom: [],
};
const builtinStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
t.deepEqual(Object.keys(builtinStatusReport).length, 1);
t.true(`analyze_builtin_queries_${language}_duration_ms` in builtinStatusReport);
const hasPacks = language in packs;
const statusReportKeys = Object.keys(builtinStatusReport).sort();
if (hasPacks) {
t.deepEqual(statusReportKeys.length, 3, statusReportKeys.toString());
t.deepEqual(statusReportKeys[0], `analyze_builtin_queries_${language}_duration_ms`);
t.deepEqual(statusReportKeys[1], `analyze_custom_queries_${language}_duration_ms`);
t.deepEqual(statusReportKeys[2], `interpret_results_${language}_duration_ms`);
}
else {
t.deepEqual(statusReportKeys[0], `analyze_builtin_queries_${language}_duration_ms`);
t.deepEqual(statusReportKeys[1], `interpret_results_${language}_duration_ms`);
}
config.queries[language] = {
builtin: [],
custom: [
@@ -114,17 +144,21 @@ ava_1.default("status report fields and search path setting", async (t) => {
],
};
const customStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
t.deepEqual(Object.keys(customStatusReport).length, 1);
t.deepEqual(Object.keys(customStatusReport).length, 2);
t.true(`analyze_custom_queries_${language}_duration_ms` in customStatusReport);
t.deepEqual(searchPathsUsed, [undefined, "/1", "/2"]);
const expectedSearchPathsUsed = hasPacks
? [undefined, undefined, "/1", "/2", undefined]
: [undefined, "/1", "/2"];
t.deepEqual(searchPathsUsed, expectedSearchPathsUsed);
t.true(`interpret_results_${language}_duration_ms` in customStatusReport);
}
verifyLineCounts(tmpDir);
verifyQuerySuites(tmpDir);
});
function verifyLineCounts(tmpDir) {
// eslint-disable-next-line github/array-foreach
Object.keys(languages_1.Language).forEach((lang, i) => {
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}-builtin.sarif`), i + 1);
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}-custom.sarif`), i + 1);
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}.sarif`), i + 1);
});
}
function verifyLineCountForFile(lang, filePath, lineCount) {
@@ -146,8 +180,52 @@ ava_1.default("status report fields and search path setting", async (t) => {
baseline: lineCount,
},
]);
// when the rule doesn't exists, it should not be added
// when the rule doesn't exist, it should not be added
t.deepEqual(sarif.runs[2].properties.metricResults, []);
}
function verifyQuerySuites(tmpDir) {
const qlsContent = [
{
query: "foo.ql",
},
];
const qlsContent2 = [
{
query: "bar.ql",
},
];
const qlsPackContentCpp = [
{
qlpack: "a/b",
version: "1.0.0",
},
];
const qlsPackContentJava = [
{
qlpack: "c/d",
version: "2.0.0",
},
];
for (const lang of Object.values(languages_1.Language)) {
t.deepEqual(readContents(`${lang}-queries-builtin.qls`), qlsContent);
t.deepEqual(readContents(`${lang}-queries-custom-0.qls`), qlsContent);
t.deepEqual(readContents(`${lang}-queries-custom-1.qls`), qlsContent2);
const packSuiteName = `${lang}-queries-packs.qls`;
if (lang === languages_1.Language.cpp) {
t.deepEqual(readContents(packSuiteName), qlsPackContentCpp);
}
else if (lang === languages_1.Language.java) {
t.deepEqual(readContents(packSuiteName), qlsPackContentJava);
}
else {
t.false(fs.existsSync(path.join(tmpDir, "codeql_databases", packSuiteName)));
}
}
function readContents(name) {
const x = fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8");
console.log(x);
return yaml.safeLoad(fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8"));
}
}
});
//# sourceMappingURL=analyze.test.js.map

File diff suppressed because one or more lines are too long

19
lib/api-client.js generated
View File

@@ -12,22 +12,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("path"));
const githubUtils = __importStar(require("@actions/github/lib/utils"));
const retry = __importStar(require("@octokit/plugin-retry"));
const console_log_level_1 = __importDefault(require("console-log-level"));
const actions_util_1 = require("./actions-util");
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
var DisallowedAPIVersionReason;
(function (DisallowedAPIVersionReason) {
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_OLD"] = 0] = "ACTION_TOO_OLD";
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_NEW"] = 1] = "ACTION_TOO_NEW";
})(DisallowedAPIVersionReason = exports.DisallowedAPIVersionReason || (exports.DisallowedAPIVersionReason = {}));
exports.getApiClient = function (apiDetails, { allowLocalRun = false, allowExternal = false } = {}) {
if (util_1.isLocalRun() && !allowLocalRun) {
throw new Error("Invalid API call in local run");
}
exports.getApiClient = function (apiDetails, { allowExternal = false } = {}) {
const auth = (allowExternal && apiDetails.externalRepoAuth) || apiDetails.auth;
return new githubUtils.GitHub(githubUtils.getOctokitOptions(auth, {
const retryingOctokit = githubUtils.GitHub.plugin(retry.retry);
return new retryingOctokit(githubUtils.getOctokitOptions(auth, {
baseUrl: getApiUrl(apiDetails.url),
userAgent: "CodeQL Action",
userAgent: `CodeQL-${util_1.getMode()}/${pkg.version}`,
log: console_log_level_1.default({ level: "debug" }),
}));
};
@@ -45,12 +46,12 @@ function getApiUrl(githubUrl) {
// Temporary function to aid in the transition to running on and off of github actions.
// Once all code has been converted this function should be removed or made canonical
// and called only from the action entrypoints.
function getActionsApiClient(allowLocalRun = false) {
function getActionsApiClient() {
const apiDetails = {
auth: actions_util_1.getRequiredInput("token"),
url: actions_util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
};
return exports.getApiClient(apiDetails, { allowLocalRun });
return exports.getApiClient(apiDetails);
}
exports.getActionsApiClient = getActionsApiClient;
//# sourceMappingURL=api-client.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA6B;AAE7B,uEAAyD;AACzD,0EAAgD;AAEhD,iDAAuE;AACvE,iCAAoC;AAEpC,IAAY,0BAGX;AAHD,WAAY,0BAA0B;IACpC,+FAAc,CAAA;IACd,+FAAc,CAAA;AAChB,CAAC,EAHW,0BAA0B,GAA1B,kCAA0B,KAA1B,kCAA0B,QAGrC;AAeY,QAAA,YAAY,GAAG,UAC1B,UAAoC,EACpC,EAAE,aAAa,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,EAAE,GAAG,EAAE;IAErD,IAAI,iBAAU,EAAE,IAAI,CAAC,aAAa,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;KAClD;IAED,MAAM,IAAI,GACR,CAAC,aAAa,IAAI,UAAU,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;IACpE,OAAO,IAAI,WAAW,CAAC,MAAM,CAC3B,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAClC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAClC,SAAS,EAAE,eAAe;QAC1B,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAE/B,uDAAuD;IACvD,0CAA0C;IAC1C,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,GAAG,CAAC,QAAQ,KAAK,gBAAgB,EAAE;QACtE,OAAO,wBAAwB,CAAC;KACjC;IAED,6BAA6B;IAC7B,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,uFAAuF;AACvF,qFAAqF;AACrF,+CAA+C;AAC/C,SAAgB,mBAAmB,CAAC,aAAa,GAAG,KAAK;IACvD,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,+BAAgB,CAAC,OAAO,CAAC;QAC/B,GAAG,EAAE,kCAAmB,CAAC,mBAAmB,CAAC;KAC9C,CAAC;IAEF,OAAO,oBAAY,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;AACrD,CAAC;AAPD,kDAOC"}
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA6B;AAE7B,uEAAyD;AACzD,6DAA+C;AAC/C,0EAAgD;AAEhD,iDAAkD;AAClD,iCAAsD;AAEtD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,IAAY,0BAGX;AAHD,WAAY,0BAA0B;IACpC,+FAAc,CAAA;IACd,+FAAc,CAAA;AAChB,CAAC,EAHW,0BAA0B,GAA1B,kCAA0B,KAA1B,kCAA0B,QAGrC;AAeY,QAAA,YAAY,GAAG,UAC1B,UAAoC,EACpC,EAAE,aAAa,GAAG,KAAK,EAAE,GAAG,EAAE;IAE9B,MAAM,IAAI,GACR,CAAC,aAAa,IAAI,UAAU,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;IACpE,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,IAAI,eAAe,CACxB,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAClC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAClC,SAAS,EAAE,UAAU,cAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE;QAC/C,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAE/B,uDAAuD;IACvD,0CAA0C;IAC1C,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,GAAG,CAAC,QAAQ,KAAK,gBAAgB,EAAE;QACtE,OAAO,wBAAwB,CAAC;KACjC;IAED,6BAA6B;IAC7B,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,uFAAuF;AACvF,qFAAqF;AACrF,+CAA+C;AAC/C,SAAgB,mBAAmB;IACjC,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,+BAAgB,CAAC,OAAO,CAAC;QAC/B,GAAG,EAAE,0BAAmB,CAAC,mBAAmB,CAAC;KAC9C,CAAC;IAEF,OAAO,oBAAY,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAPD,kDAOC"}

17
lib/api-client.test.js generated
View File

@@ -15,10 +15,17 @@ const ava_1 = __importDefault(require("ava"));
const sinon_1 = __importDefault(require("sinon"));
const api_client_1 = require("./api-client");
const testing_utils_1 = require("./testing-utils");
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
testing_utils_1.setupTests(ava_1.default);
let pluginStub;
let githubStub;
ava_1.default.beforeEach(() => {
githubStub = sinon_1.default.stub(githubUtils, "GitHub");
pluginStub = sinon_1.default.stub(githubUtils.GitHub, "plugin");
githubStub = sinon_1.default.stub();
pluginStub.returns(githubStub);
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
});
ava_1.default("Get the client API", async (t) => {
doTest(t, {
@@ -28,7 +35,7 @@ ava_1.default("Get the client API", async (t) => {
}, undefined, {
auth: "token xyz",
baseUrl: "http://hucairz/api/v3",
userAgent: "CodeQL Action",
userAgent: `CodeQL-Action/${pkg.version}`,
});
});
ava_1.default("Get the client API external", async (t) => {
@@ -39,7 +46,7 @@ ava_1.default("Get the client API external", async (t) => {
}, { allowExternal: true }, {
auth: "token abc",
baseUrl: "http://hucairz/api/v3",
userAgent: "CodeQL Action",
userAgent: `CodeQL-Action/${pkg.version}`,
});
});
ava_1.default("Get the client API external not present", async (t) => {
@@ -49,7 +56,7 @@ ava_1.default("Get the client API external not present", async (t) => {
}, { allowExternal: true }, {
auth: "token xyz",
baseUrl: "http://hucairz/api/v3",
userAgent: "CodeQL Action",
userAgent: `CodeQL-Action/${pkg.version}`,
});
});
ava_1.default("Get the client API with github url", async (t) => {
@@ -59,7 +66,7 @@ ava_1.default("Get the client API with github url", async (t) => {
}, undefined, {
auth: "token xyz",
baseUrl: "https://api.github.com",
userAgent: "CodeQL Action",
userAgent: `CodeQL-Action/${pkg.version}`,
});
});
function doTest(t, clientArgs, clientOptions, expected) {

View File

@@ -1 +1 @@
{"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../src/api-client.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uEAAyD;AACzD,8CAA6C;AAC7C,kDAA0B;AAE1B,6CAA4C;AAC5C,mDAA6C;AAE7C,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,IAAI,UAA2B,CAAC;AAEhC,aAAI,CAAC,UAAU,CAAC,GAAG,EAAE;IACnB,UAAU,GAAG,eAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrC,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,eAAe;KAC3B,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,6BAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9C,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,eAAe;KAC3B,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,yCAAyC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1D,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,eAAe;KAC3B,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oCAAoC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrD,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,qCAAqC;KAC3C,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,wBAAwB;QACjC,SAAS,EAAE,eAAe;KAC3B,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,MAAM,CACb,CAA4B,EAC5B,UAAe,EACf,aAAkB,EAClB,QAAa;IAEb,yBAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAExC,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,iEAAiE;IACjE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5B,CAAC,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzC,CAAC"}
{"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../src/api-client.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uEAAyD;AACzD,8CAA6C;AAC7C,kDAA0B;AAE1B,6CAA4C;AAC5C,mDAA6C;AAC7C,iCAAqD;AAErD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,IAAI,UAA2B,CAAC;AAChC,IAAI,UAA2B,CAAC;AAEhC,aAAI,CAAC,UAAU,CAAC,GAAG,EAAE;IACnB,UAAU,GAAG,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,UAAU,GAAG,eAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrC,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,6BAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9C,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,yCAAyC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1D,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oCAAoC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrD,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,qCAAqC;KAC3C,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,wBAAwB;QACjC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,MAAM,CACb,CAA4B,EAC5B,UAAe,EACf,aAAkB,EAClB,QAAa;IAEb,yBAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAExC,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,iEAAiE;IACjE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5B,CAAC,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzC,CAAC"}

View File

@@ -1 +1 @@
{ "maximumVersion": "3.1", "minimumVersion": "2.22" }
{ "maximumVersion": "3.2", "minimumVersion": "2.22" }

View File

@@ -8,33 +8,36 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const actionsUtil = __importStar(require("./actions-util"));
const actions_util_1 = require("./actions-util");
const autobuild_1 = require("./autobuild");
const config_utils = __importStar(require("./config-utils"));
const logging_1 = require("./logging");
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
async function sendCompletedStatusReport(startedAt, allLanguages, failingLanguage, cause) {
var _a, _b;
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
const status = failingLanguage !== undefined || cause !== undefined
? "failure"
: "success";
const statusReportBase = await actionsUtil.createStatusReportBase("autobuild", status, startedAt, (_a = cause) === null || _a === void 0 ? void 0 : _a.message, (_b = cause) === null || _b === void 0 ? void 0 : _b.stack);
const statusReportBase = await actions_util_1.createStatusReportBase("autobuild", status, startedAt, (_a = cause) === null || _a === void 0 ? void 0 : _a.message, (_b = cause) === null || _b === void 0 ? void 0 : _b.stack);
const statusReport = {
...statusReportBase,
autobuild_languages: allLanguages.join(","),
autobuild_failure: failingLanguage,
};
await actionsUtil.sendStatusReport(statusReport);
await actions_util_1.sendStatusReport(statusReport);
}
async function run() {
const logger = logging_1.getActionsLogger();
const startedAt = new Date();
let language = undefined;
try {
actionsUtil.prepareLocalRunEnvironment();
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("autobuild", "starting", startedAt)))) {
if (!(await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("autobuild", "starting", startedAt)))) {
return;
}
const config = await config_utils.getConfig(actionsUtil.getTemporaryDirectory(), logger);
const config = await config_utils.getConfig(actions_util_1.getTemporaryDirectory(), logger);
if (config === undefined) {
throw new Error("Config file could not be found at expected location. Has the 'init' action been called?");
}

View File

@@ -1 +1 @@
{"version":3,"file":"autobuild-action.js","sourceRoot":"","sources":["../src/autobuild-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,2CAAuE;AACvE,6DAA+C;AAE/C,uCAA6C;AAS7C,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,MAAM,MAAM,GACV,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAClD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CACb,CAAC;IACF,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAyB,SAAS,CAAC;IAC/C,IAAI;QACF,WAAW,CAAC,0BAA0B,EAAE,CAAC;QACzC,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,WAAW,EACX,UAAU,EACV,SAAS,CACV,CACF,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CACzC,WAAW,CAAC,qBAAqB,EAAE,EACnC,MAAM,CACP,CAAC;QACF,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;SACH;QACD,QAAQ,GAAG,sCAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,QAAQ,KAAK,SAAS,EAAE;YAC1B,MAAM,wBAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9C;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CACZ,mIAAmI,KAAK,CAAC,OAAO,EAAE,CACnJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,yBAAyB,CAC7B,SAAS,EACT,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAC1B,QAAQ,EACR,KAAK,CACN,CAAC;QACF,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
{"version":3,"file":"autobuild-action.js","sourceRoot":"","sources":["../src/autobuild-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,iDAKwB;AACxB,2CAAuE;AACvE,6DAA+C;AAE/C,uCAA6C;AAC7C,iCAAqD;AAErD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AASvC,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GACV,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAClD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,gBAAgB,GAAG,MAAM,qCAAsB,CACnD,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CACb,CAAC;IACF,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,+BAAgB,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAyB,SAAS,CAAC;IAC/C,IAAI;QACF,IACE,CAAC,CAAC,MAAM,+BAAgB,CACtB,MAAM,qCAAsB,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CACjE,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CACzC,oCAAqB,EAAE,EACvB,MAAM,CACP,CAAC;QACF,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;SACH;QACD,QAAQ,GAAG,sCAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,QAAQ,KAAK,SAAS,EAAE;YAC1B,MAAM,wBAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9C;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CACZ,mIAAmI,KAAK,CAAC,OAAO,EAAE,CACnJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,yBAAyB,CAC7B,SAAS,EACT,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAC1B,QAAQ,EACR,KAAK,CACN,CAAC;QACF,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}

229
lib/codeql.js generated
View File

@@ -12,14 +12,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const stream = __importStar(require("stream"));
const globalutil = __importStar(require("util"));
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
const http = __importStar(require("@actions/http-client"));
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
const query_string_1 = __importDefault(require("query-string"));
const semver = __importStar(require("semver"));
const uuid_1 = require("uuid");
const actions_util_1 = require("./actions-util");
const api = __importStar(require("./api-client"));
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
@@ -27,6 +23,14 @@ const error_matcher_1 = require("./error-matcher");
const toolcache = __importStar(require("./toolcache"));
const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
const util = __importStar(require("./util"));
class CommandInvocationError extends Error {
constructor(cmd, args, exitCode, error) {
super(`Failure invoking ${cmd} with arguments ${args}.\n
Exit code ${exitCode} and error was:\n
${error}`);
}
}
exports.CommandInvocationError = CommandInvocationError;
/**
* Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`.
* Can be overridden in tests using `setCodeQL`.
@@ -50,14 +54,15 @@ function getCodeQLBundleName() {
}
return `codeql-bundle-${platform}.tar.gz`;
}
function getCodeQLActionRepository(mode, logger) {
if (mode !== "actions") {
function getCodeQLActionRepository(logger) {
if (!util.isActions()) {
return CODEQL_DEFAULT_ACTION_REPOSITORY;
}
else {
return getActionsCodeQLActionRepository(logger);
}
}
exports.getCodeQLActionRepository = getCodeQLActionRepository;
function getActionsCodeQLActionRepository(logger) {
if (process.env["GITHUB_ACTION_REPOSITORY"] !== undefined) {
return process.env["GITHUB_ACTION_REPOSITORY"];
@@ -74,8 +79,8 @@ function getActionsCodeQLActionRepository(logger) {
const relativeScriptPathParts = actions_util_1.getRelativeScriptPath().split(path.sep);
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
}
async function getCodeQLBundleDownloadURL(apiDetails, mode, variant, logger) {
const codeQLActionRepository = getCodeQLActionRepository(mode, logger);
async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
const codeQLActionRepository = getCodeQLActionRepository(logger);
const potentialDownloadSources = [
// This GitHub instance, and this Action.
[apiDetails.url, codeQLActionRepository],
@@ -141,22 +146,7 @@ async function getCodeQLBundleDownloadURL(apiDetails, mode, variant, logger) {
}
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${codeQLBundleName}`;
}
// We have to download CodeQL manually because the toolcache doesn't support Accept headers.
// This can be removed once https://github.com/actions/toolkit/pull/530 is merged and released.
async function toolcacheDownloadTool(url, headers, tempDir, logger) {
const client = new http.HttpClient("CodeQL Action");
const dest = path.join(tempDir, uuid_1.v4());
const response = await client.get(url, headers);
if (response.message.statusCode !== 200) {
logger.info(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
throw new Error(`Unexpected HTTP response: ${response.message.statusCode}`);
}
const pipeline = globalutil.promisify(stream.pipeline);
fs.mkdirSync(path.dirname(dest), { recursive: true });
await pipeline(response.message, fs.createWriteStream(dest));
return dest;
}
async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, variant, logger) {
async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger) {
try {
// We use the special value of 'latest' to prioritize the version in the
// defaults over any pinned cached version.
@@ -167,14 +157,14 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, v
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`);
const codeqlURLSemVer = convertToSemVer(codeqlURLVersion, logger);
// If we find the specified version, we always use that.
let codeqlFolder = toolcache.find("CodeQL", codeqlURLSemVer, mode, toolCacheDir, logger);
let codeqlFolder = toolcache.find("CodeQL", codeqlURLSemVer, toolCacheDir, logger);
// If we don't find the requested version, in some cases we may allow a
// different version to save download time if the version hasn't been
// specified explicitly (in which case we always honor it).
if (!codeqlFolder && !codeqlURL && !forceLatest) {
const codeqlVersions = toolcache.findAllVersions("CodeQL", mode, toolCacheDir, logger);
const codeqlVersions = toolcache.findAllVersions("CodeQL", toolCacheDir, logger);
if (codeqlVersions.length === 1) {
const tmpCodeqlFolder = toolcache.find("CodeQL", codeqlVersions[0], mode, toolCacheDir, logger);
const tmpCodeqlFolder = toolcache.find("CodeQL", codeqlVersions[0], toolCacheDir, logger);
if (fs.existsSync(path.join(tmpCodeqlFolder, "pinned-version"))) {
logger.debug(`CodeQL in cache overriding the default ${CODEQL_BUNDLE_VERSION}`);
codeqlFolder = tmpCodeqlFolder;
@@ -186,7 +176,7 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, v
}
else {
if (!codeqlURL) {
codeqlURL = await getCodeQLBundleDownloadURL(apiDetails, mode, variant, logger);
codeqlURL = await getCodeQLBundleDownloadURL(apiDetails, variant, logger);
}
const parsedCodeQLURL = new URL(codeqlURL);
const parsedQueryString = query_string_1.default.parse(parsedCodeQLURL.search);
@@ -204,10 +194,10 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, v
logger.debug("Downloading CodeQL bundle without token.");
}
logger.info(`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`);
const codeqlPath = await toolcacheDownloadTool(codeqlURL, headers, tempDir, logger);
const codeqlPath = await toolcache.downloadTool(codeqlURL, tempDir, headers);
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
const codeqlExtracted = await toolcache.extractTar(codeqlPath, mode, tempDir, logger);
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLSemVer, mode, toolCacheDir, logger);
const codeqlExtracted = await toolcache.extractTar(codeqlPath, tempDir, logger);
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLSemVer, toolCacheDir, logger);
}
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
if (process.platform === "win32") {
@@ -282,8 +272,13 @@ function setCodeQL(partialCodeql) {
runAutobuild: resolveFunction(partialCodeql, "runAutobuild"),
extractScannedLanguage: resolveFunction(partialCodeql, "extractScannedLanguage"),
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
databaseAnalyze: resolveFunction(partialCodeql, "databaseAnalyze"),
packDownload: resolveFunction(partialCodeql, "packDownload"),
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
databaseBundle: resolveFunction(partialCodeql, "databaseBundle"),
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
};
return cachedCodeQL;
}
@@ -308,7 +303,7 @@ function getCodeQLForCmd(cmd) {
return cmd;
},
async printVersion() {
await new toolrunner.ToolRunner(cmd, ["version", "--format=json"]).exec();
await runTool(cmd, ["version", "--format=json"]);
},
async getTracerEnv(databasePath) {
// Write tracer-env.js to a temp location.
@@ -339,7 +334,7 @@ function getCodeQLForCmd(cmd) {
// action/runner has been implemented in `codeql database trace-command`
// _and_ is present in the latest supported CLI release.)
const envFile = path.resolve(databasePath, "working", "env.tmp");
await new toolrunner.ToolRunner(cmd, [
await runTool(cmd, [
"database",
"trace-command",
databasePath,
@@ -347,18 +342,18 @@ function getCodeQLForCmd(cmd) {
process.execPath,
tracerEnvJs,
envFile,
]).exec();
]);
return JSON.parse(fs.readFileSync(envFile, "utf-8"));
},
async databaseInit(databasePath, language, sourceRoot) {
await new toolrunner.ToolRunner(cmd, [
await runTool(cmd, [
"database",
"init",
databasePath,
`--language=${language}`,
`--source-root=${sourceRoot}`,
...getExtraOptionsFromEnv(["database", "init"]),
]).exec();
]);
},
async runAutobuild(language) {
const cmdName = process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh";
@@ -374,7 +369,7 @@ function getCodeQLForCmd(cmd) {
"-Dhttp.keepAlive=false",
"-Dmaven.wagon.http.pool=false",
].join(" ");
await new toolrunner.ToolRunner(autobuildCmd).exec();
await runTool(autobuildCmd);
},
async extractScannedLanguage(databasePath, language) {
// Get extractor location
@@ -413,11 +408,22 @@ function getCodeQLForCmd(cmd) {
await toolrunner_error_catcher_1.toolrunnerErrorCatcher(cmd, [
"database",
"finalize",
"--finalize-dataset",
threadsFlag,
...getExtraOptionsFromEnv(["database", "finalize"]),
databasePath,
], error_matcher_1.errorMatchers);
},
async resolveLanguages() {
const codeqlArgs = ["resolve", "languages", "--format=json"];
const output = await runTool(cmd, codeqlArgs);
try {
return JSON.parse(output);
}
catch (e) {
throw new Error(`Unexpected output from codeql resolve languages: ${e}`);
}
},
async resolveQueries(queries, extraSearchPath) {
const codeqlArgs = [
"resolve",
@@ -429,53 +435,110 @@ function getCodeQLForCmd(cmd) {
if (extraSearchPath !== undefined) {
codeqlArgs.push("--additional-packs", extraSearchPath);
}
let output = "";
await new toolrunner.ToolRunner(cmd, codeqlArgs, {
listeners: {
stdout: (data) => {
output += data.toString();
},
},
}).exec();
return JSON.parse(output);
const output = await runTool(cmd, codeqlArgs);
try {
return JSON.parse(output);
}
catch (e) {
throw new Error(`Unexpected output from codeql resolve queries: ${e}`);
}
},
async databaseAnalyze(databasePath, sarifFile, extraSearchPath, querySuite, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId) {
const args = [
async databaseRunQueries(databasePath, extraSearchPath, querySuitePath, memoryFlag, threadsFlag) {
const codeqlArgs = [
"database",
"analyze",
"run-queries",
memoryFlag,
threadsFlag,
databasePath,
"--min-disk-free=1024",
"--format=sarif-latest",
"--sarif-multicause-markdown",
`--output=${sarifFile}`,
addSnippetsFlag,
// Enable progress verbosity so we log each query as it's interpreted. This aids debugging
// when interpretation takes a while for one of the queries being analyzed.
"-v",
...getExtraOptionsFromEnv(["database", "analyze"]),
...getExtraOptionsFromEnv(["database", "run-queries"]),
];
if (extraSearchPath !== undefined) {
args.push("--additional-packs", extraSearchPath);
codeqlArgs.push("--additional-packs", extraSearchPath);
}
codeqlArgs.push(querySuitePath);
await runTool(cmd, codeqlArgs);
},
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId) {
const codeqlArgs = [
"database",
"interpret-results",
threadsFlag,
"--format=sarif-latest",
"--print-metrics-summary",
"--sarif-group-rules-by-pack",
"-v",
`--output=${sarifFile}`,
addSnippetsFlag,
...getExtraOptionsFromEnv(["database", "interpret-results"]),
];
if (automationDetailsId !== undefined) {
args.push("--sarif-category", automationDetailsId);
codeqlArgs.push("--sarif-category", automationDetailsId);
}
args.push(querySuite);
codeqlArgs.push(databasePath, ...querySuitePaths);
// capture stdout, which contains analysis summaries
let output = "";
await new toolrunner.ToolRunner(cmd, args, {
listeners: {
stdout: (data) => {
output += data.toString("utf8");
},
},
}).exec();
return output;
return await runTool(cmd, codeqlArgs);
},
/**
* Download specified packs into the package cache. If the specified
* package and version already exists (e.g., from a previous analysis run),
* then it is not downloaded again (unless the extra option `--force` is
* specified).
*
* If no version is specified, then the latest version is
* downloaded. The check to determine what the latest version is is done
* each time this package is requested.
*/
async packDownload(packs) {
const codeqlArgs = [
"pack",
"download",
"--format=json",
...getExtraOptionsFromEnv(["pack", "download"]),
...packs.map(packWithVersionToString),
];
const output = await runTool(cmd, codeqlArgs);
try {
const parsedOutput = JSON.parse(output);
if (Array.isArray(parsedOutput.packs) &&
// TODO PackDownloadOutput will not include the version if it is not specified
// in the input. The version is always the latest version available.
// It should be added to the output, but this requires a CLI change
parsedOutput.packs.every((p) => p.name /* && p.version */)) {
return parsedOutput;
}
else {
throw new Error("Unexpected output from pack download");
}
}
catch (e) {
throw new Error(`Attempted to download specified packs but got an error:\n${output}\n${e}`);
}
},
async databaseCleanup(databasePath, cleanupLevel) {
const codeqlArgs = [
"database",
"cleanup",
databasePath,
`--mode=${cleanupLevel}`,
];
await runTool(cmd, codeqlArgs);
},
async databaseBundle(databasePath, outputFilePath) {
const args = [
"database",
"bundle",
databasePath,
`--output=${outputFilePath}`,
];
await new toolrunner.ToolRunner(cmd, args).exec();
},
};
}
function packWithVersionToString(pack) {
return pack.version ? `${pack.packName}@${pack.version}` : pack.packName;
}
/**
* Gets the options for `path` of `options` as an array of extra option strings.
*/
@@ -522,4 +585,32 @@ function getExtraOptions(options, paths, pathInfo) {
return all.concat(specific);
}
exports.getExtraOptions = getExtraOptions;
/*
* A constant defining the maximum number of characters we will keep from
* the programs stderr for logging. This serves two purposes:
* (1) It avoids an OOM if a program fails in a way that results it
* printing many log lines.
* (2) It avoids us hitting the limit of how much data we can send in our
* status reports on GitHub.com.
*/
const maxErrorSize = 20000;
async function runTool(cmd, args = []) {
let output = "";
let error = "";
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
listeners: {
stdout: (data) => {
output += data.toString();
},
stderr: (data) => {
const toRead = Math.min(maxErrorSize - error.length, data.length);
error += data.toString("utf8", 0, toRead);
},
},
ignoreReturnCode: true,
}).exec();
if (exitCode !== 0)
throw new CommandInvocationError(cmd, args, exitCode, error);
return output;
}
//# sourceMappingURL=codeql.js.map

File diff suppressed because one or more lines are too long

39
lib/codeql.test.js generated
View File

@@ -19,6 +19,7 @@ const defaults = __importStar(require("./defaults.json"));
const logging_1 = require("./logging");
const testing_utils_1 = require("./testing-utils");
const util = __importStar(require("./util"));
const util_1 = require("./util");
testing_utils_1.setupTests(ava_1.default);
const sampleApiDetails = {
auth: "token",
@@ -28,6 +29,9 @@ const sampleGHAEApiDetails = {
auth: "token",
url: "https://example.githubenterprise.com",
};
ava_1.default.beforeEach(() => {
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
});
ava_1.default("download codeql bundle cache", async (t) => {
await util.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
@@ -37,7 +41,7 @@ ava_1.default("download codeql bundle cache", async (t) => {
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
}
const cachedVersions = toolcache.findAllVersions("CodeQL");
@@ -50,12 +54,12 @@ ava_1.default("download codeql bundle cache explicitly requested with pinned dif
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-20200610/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200610/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200610/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
});
});
@@ -65,9 +69,9 @@ ava_1.default("don't download codeql bundle cache with pinned different version
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
const cachedVersions = toolcache.findAllVersions("CodeQL");
t.is(cachedVersions.length, 1);
});
@@ -78,7 +82,7 @@ ava_1.default("download codeql bundle cache with different version cached (not p
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
const platform = process.platform === "win32"
? "win64"
@@ -88,7 +92,7 @@ ava_1.default("download codeql bundle cache with different version cached (not p
nock_1.default("https://github.com")
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/codeql-bundle-${platform}.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
const cachedVersions = toolcache.findAllVersions("CodeQL");
t.is(cachedVersions.length, 2);
});
@@ -99,7 +103,7 @@ ava_1.default('download codeql bundle cache with pinned different version cached
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
const platform = process.platform === "win32"
? "win64"
@@ -109,7 +113,7 @@ ava_1.default('download codeql bundle cache with pinned different version cached
nock_1.default("https://github.com")
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/codeql-bundle-${platform}.tar.gz`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
const cachedVersions = toolcache.findAllVersions("CodeQL");
t.is(cachedVersions.length, 2);
});
@@ -137,7 +141,7 @@ ava_1.default("download codeql bundle from github ae endpoint", async (t) => {
nock_1.default("https://example.githubenterprise.com")
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`)
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, tmpDir, "runner", util.GitHubVariant.GHAE, logging_1.getRunnerLogger(true));
await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, tmpDir, util.GitHubVariant.GHAE, logging_1.getRunnerLogger(true));
const cachedVersions = toolcache.findAllVersions("CodeQL");
t.is(cachedVersions.length, 1);
});
@@ -186,4 +190,19 @@ ava_1.default("getExtraOptions throws for bad content", (t) => {
t.throws(() => codeql.getExtraOptions({ foo: 87 }, ["foo"], []));
t.throws(() => codeql.getExtraOptions({ "*": [42], foo: { "*": 87, bar: [99] } }, ["foo", "bar"], []));
});
ava_1.default("getCodeQLActionRepository", (t) => {
const logger = logging_1.getRunnerLogger(true);
util_1.initializeEnvironment(util_1.Mode.runner, "1.2.3");
const repoActions = codeql.getCodeQLActionRepository(logger);
t.deepEqual(repoActions, "github/codeql-action");
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
// isRunningLocalAction() === true
delete process.env["GITHUB_ACTION_REPOSITORY"];
process.env["RUNNER_TEMP"] = path.dirname(__dirname);
const repoLocalRunner = codeql.getCodeQLActionRepository(logger);
t.deepEqual(repoLocalRunner, "github/codeql-action");
process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy";
const repoEnv = codeql.getCodeQLActionRepository(logger);
t.deepEqual(repoEnv, "xxx/yyy");
});
//# sourceMappingURL=codeql.test.js.map

File diff suppressed because one or more lines are too long

183
lib/config-utils.js generated
View File

@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yaml = __importStar(require("js-yaml"));
const semver = __importStar(require("semver"));
const api = __importStar(require("./api-client"));
const externalQueries = __importStar(require("./external-queries"));
const languages_1 = require("./languages");
@@ -20,6 +21,7 @@ const QUERIES_PROPERTY = "queries";
const QUERIES_USES_PROPERTY = "uses";
const PATHS_IGNORE_PROPERTY = "paths-ignore";
const PATHS_PROPERTY = "paths";
const PACKS_PROPERTY = "packs";
/**
* A list of queries from https://github.com/github/codeql that
* we don't want to run. Disabling them here is a quicker alternative to
@@ -254,6 +256,24 @@ function getPathsInvalid(configFile) {
return getConfigFilePropertyError(configFile, PATHS_PROPERTY, "must be an array of non-empty strings");
}
exports.getPathsInvalid = getPathsInvalid;
function getPacksRequireLanguage(lang, configFile) {
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, `has "${lang}", but it is not one of the languages to analyze`);
}
exports.getPacksRequireLanguage = getPacksRequireLanguage;
function getPacksInvalidSplit(configFile) {
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, "must split packages by language");
}
exports.getPacksInvalidSplit = getPacksInvalidSplit;
function getPacksInvalid(configFile) {
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, "must be an array of non-empty strings");
}
exports.getPacksInvalid = getPacksInvalid;
function getPacksStrInvalid(packStr, configFile) {
return configFile
? getConfigFilePropertyError(configFile, PACKS_PROPERTY, `"${packStr}" is not a valid pack`)
: `"${packStr}" is not a valid pack`;
}
exports.getPacksStrInvalid = getPacksStrInvalid;
function getLocalPathOutsideOfRepository(configFile, localPath) {
return getConfigFilePropertyError(configFile, `${QUERIES_PROPERTY}.${QUERIES_USES_PROPERTY}`, `is invalid as the local path "${localPath}" is outside of the repository`);
}
@@ -306,9 +326,7 @@ exports.getUnknownLanguagesError = getUnknownLanguagesError;
*/
async function getLanguagesInRepo(repository, apiDetails, logger) {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api
.getApiClient(apiDetails, { allowLocalRun: true })
.repos.listLanguages({
const response = await api.getApiClient(apiDetails).repos.listLanguages({
owner: repository.owner,
repo: repository.repo,
});
@@ -336,7 +354,7 @@ async function getLanguagesInRepo(repository, apiDetails, logger) {
* If no languages could be detected from either the workflow or the repository
* then throw an error.
*/
async function getLanguages(languagesInput, repository, apiDetails, logger) {
async function getLanguages(codeQL, languagesInput, repository, apiDetails, logger) {
// Obtain from action input 'languages' if set
let languages = (languagesInput || "")
.split(",")
@@ -346,6 +364,8 @@ async function getLanguages(languagesInput, repository, apiDetails, logger) {
if (languages.length === 0) {
// Obtain languages as all languages in the repo that can be analysed
languages = await getLanguagesInRepo(repository, apiDetails, logger);
const availableLanguages = await codeQL.resolveLanguages();
languages = languages.filter((value) => value in availableLanguages);
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
}
// If the languages parameter was not given and no languages were
@@ -391,8 +411,9 @@ function shouldAddConfigFileQueries(queriesInput) {
/**
* Get the default config for when the user has not supplied one.
*/
async function getDefaultConfig(languagesInput, queriesInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
const languages = await getLanguages(languagesInput, repository, apiDetails, logger);
async function getDefaultConfig(languagesInput, queriesInput, packsInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
var _a;
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
const queries = {};
for (const language of languages) {
queries[language] = {
@@ -404,11 +425,13 @@ async function getDefaultConfig(languagesInput, queriesInput, dbLocation, reposi
if (queriesInput) {
await addQueriesFromWorkflow(codeQL, queriesInput, languages, queries, tempDir, checkoutPath, apiDetails, logger);
}
const packs = (_a = parsePacksFromInput(packsInput, languages), (_a !== null && _a !== void 0 ? _a : {}));
return {
languages,
queries,
pathsIgnore: [],
paths: [],
packs,
originalUserInput: {},
tempDir,
toolCacheDir,
@@ -421,7 +444,8 @@ exports.getDefaultConfig = getDefaultConfig;
/**
* Load the config from the given file.
*/
async function loadConfig(languagesInput, queriesInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
async function loadConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
var _a;
let parsedYAML;
if (isLocal(configFile)) {
// Treat the config file as relative to the workspace
@@ -441,7 +465,7 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
throw new Error(getNameInvalid(configFile));
}
}
const languages = await getLanguages(languagesInput, repository, apiDetails, logger);
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
const queries = {};
for (const language of languages) {
queries[language] = {
@@ -470,10 +494,11 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
}
if (shouldAddConfigFileQueries(queriesInput) &&
QUERIES_PROPERTY in parsedYAML) {
if (!(parsedYAML[QUERIES_PROPERTY] instanceof Array)) {
const queriesArr = parsedYAML[QUERIES_PROPERTY];
if (!Array.isArray(queriesArr)) {
throw new Error(getQueriesInvalid(configFile));
}
for (const query of parsedYAML[QUERIES_PROPERTY]) {
for (const query of queriesArr) {
if (!(QUERIES_USES_PROPERTY in query) ||
typeof query[QUERIES_USES_PROPERTY] !== "string") {
throw new Error(getQueryUsesInvalid(configFile));
@@ -482,7 +507,7 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
}
}
if (PATHS_IGNORE_PROPERTY in parsedYAML) {
if (!(parsedYAML[PATHS_IGNORE_PROPERTY] instanceof Array)) {
if (!Array.isArray(parsedYAML[PATHS_IGNORE_PROPERTY])) {
throw new Error(getPathsIgnoreInvalid(configFile));
}
for (const ignorePath of parsedYAML[PATHS_IGNORE_PROPERTY]) {
@@ -493,7 +518,7 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
}
}
if (PATHS_PROPERTY in parsedYAML) {
if (!(parsedYAML[PATHS_PROPERTY] instanceof Array)) {
if (!Array.isArray(parsedYAML[PATHS_PROPERTY])) {
throw new Error(getPathsInvalid(configFile));
}
for (const includePath of parsedYAML[PATHS_PROPERTY]) {
@@ -503,11 +528,13 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
paths.push(validateAndSanitisePath(includePath, PATHS_PROPERTY, configFile, logger));
}
}
const packs = parsePacks((_a = parsedYAML[PACKS_PROPERTY], (_a !== null && _a !== void 0 ? _a : {})), packsInput, languages, configFile);
return {
languages,
queries,
pathsIgnore,
paths,
packs,
originalUserInput: parsedYAML,
tempDir,
toolCacheDir,
@@ -516,6 +543,122 @@ async function loadConfig(languagesInput, queriesInput, configFile, dbLocation,
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
};
}
/**
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
* and `-` allowed as long as not the first or last char.
**/
const PACK_IDENTIFIER_PATTERN = (function () {
const alphaNumeric = "[a-z0-9]";
const alphaNumericDash = "[a-z0-9-]";
const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`;
return new RegExp(`^${component}/${component}$`);
})();
// Exported for testing
function parsePacksFromConfig(packsByLanguage, languages, configFile) {
const packs = {};
if (Array.isArray(packsByLanguage)) {
if (languages.length === 1) {
// single language analysis, so language is implicit
packsByLanguage = {
[languages[0]]: packsByLanguage,
};
}
else {
// this is an error since multi-language analysis requires
// packs split by language
throw new Error(getPacksInvalidSplit(configFile));
}
}
for (const [lang, packsArr] of Object.entries(packsByLanguage)) {
if (!Array.isArray(packsArr)) {
throw new Error(getPacksInvalid(configFile));
}
if (!languages.includes(lang)) {
throw new Error(getPacksRequireLanguage(lang, configFile));
}
packs[lang] = [];
for (const packStr of packsArr) {
packs[lang].push(toPackWithVersion(packStr, configFile));
}
}
return packs;
}
exports.parsePacksFromConfig = parsePacksFromConfig;
function parsePacksFromInput(packsInput, languages) {
var _a;
if (!((_a = packsInput) === null || _a === void 0 ? void 0 : _a.trim())) {
return undefined;
}
if (languages.length > 1) {
throw new Error("Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.");
}
else if (languages.length === 0) {
throw new Error("No languages specified. Cannot process the packs input.");
}
packsInput = packsInput.trim();
if (packsInput.startsWith("+")) {
packsInput = packsInput.substring(1).trim();
if (!packsInput) {
throw new Error("A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.");
}
}
return {
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
packs.push(toPackWithVersion(pack, ""));
return packs;
}, []),
};
}
function toPackWithVersion(packStr, configFile) {
if (typeof packStr !== "string") {
throw new Error(getPacksStrInvalid(packStr, configFile));
}
const nameWithVersion = packStr.trim().split("@");
let version;
if (nameWithVersion.length > 2 ||
!PACK_IDENTIFIER_PATTERN.test(nameWithVersion[0])) {
throw new Error(getPacksStrInvalid(packStr, configFile));
}
else if (nameWithVersion.length === 2) {
version = semver.clean(nameWithVersion[1]) || undefined;
if (!version) {
throw new Error(getPacksStrInvalid(packStr, configFile));
}
}
return {
packName: nameWithVersion[0].trim(),
version,
};
}
// exported for testing
function parsePacks(rawPacksFromConfig, rawPacksInput, languages, configFile) {
const packsFromInput = parsePacksFromInput(rawPacksInput, languages);
const packsFomConfig = parsePacksFromConfig(rawPacksFromConfig, languages, configFile);
if (!packsFromInput) {
return packsFomConfig;
}
if (!shouldCombinePacks(rawPacksInput)) {
return packsFromInput;
}
return combinePacks(packsFromInput, packsFomConfig);
}
exports.parsePacks = parsePacks;
function shouldCombinePacks(packsInput) {
var _a;
return !!((_a = packsInput) === null || _a === void 0 ? void 0 : _a.trim().startsWith("+"));
}
function combinePacks(packs1, packs2) {
const packs = {};
for (const lang of Object.keys(packs1)) {
packs[lang] = packs1[lang].concat(packs2[lang] || []);
}
for (const lang of Object.keys(packs2)) {
if (!packs[lang]) {
packs[lang] = packs2[lang];
}
}
return packs;
}
function dbLocationOrDefault(dbLocation, tempDir) {
return dbLocation || path.resolve(tempDir, "codeql_databases");
}
@@ -525,22 +668,24 @@ function dbLocationOrDefault(dbLocation, tempDir) {
* This will parse the config from the user input if present, or generate
* a default config. The parsed config is then stored to a known location.
*/
async function initConfig(languagesInput, queriesInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
async function initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
var _a, _b, _c;
let config;
// If no config file was provided create an empty one
if (!configFile) {
logger.debug("No configuration file was provided");
config = await getDefaultConfig(languagesInput, queriesInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
config = await getDefaultConfig(languagesInput, queriesInput, packsInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
}
else {
config = await loadConfig(languagesInput, queriesInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
config = await loadConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
}
// The list of queries should not be empty for any language. If it is then
// it is a user configuration error.
for (const language of config.languages) {
if (config.queries[language] === undefined ||
(config.queries[language].builtin.length === 0 &&
config.queries[language].custom.length === 0)) {
const hasBuiltinQueries = ((_a = config.queries[language]) === null || _a === void 0 ? void 0 : _a.builtin.length) > 0;
const hasCustomQueries = ((_b = config.queries[language]) === null || _b === void 0 ? void 0 : _b.custom.length) > 0;
const hasPacks = (((_c = config.packs[language]) === null || _c === void 0 ? void 0 : _c.length) || 0) > 0;
if (!hasPacks && !hasBuiltinQueries && !hasCustomQueries) {
throw new Error(`Did not detect any queries to run for ${language}. ` +
"Please make sure that the default queries are enabled, or you are specifying queries to run.");
}
@@ -577,7 +722,7 @@ async function getRemoteConfig(configFile, apiDetails) {
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
}
const response = await api
.getApiClient(apiDetails, { allowLocalRun: true, allowExternal: true })
.getApiClient(apiDetails, { allowExternal: true })
.repos.getContent({
owner: pieces.groups.owner,
repo: pieces.groups.repo,

File diff suppressed because one or more lines are too long

261
lib/config-utils.test.js generated
View File

@@ -14,6 +14,7 @@ const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const github = __importStar(require("@actions/github"));
const ava_1 = __importDefault(require("ava"));
const semver_1 = require("semver");
const sinon_1 = __importDefault(require("sinon"));
const api = __importStar(require("./api-client"));
const codeql_1 = require("./codeql");
@@ -75,8 +76,8 @@ ava_1.default("load empty config", async (t) => {
};
},
});
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger));
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger));
});
});
ava_1.default("loading config saves config", async (t) => {
@@ -98,7 +99,7 @@ ava_1.default("loading config saves config", async (t) => {
t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
// Sanity check that getConfig returns undefined before we have called initConfig
t.deepEqual(await configUtils.getConfig(tmpDir, logger), undefined);
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
// The saved config file should now exist
t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tmpDir)));
// And that same newly-initialised config should now be returned by getConfig
@@ -109,7 +110,7 @@ ava_1.default("loading config saves config", async (t) => {
ava_1.default("load input outside of workspace", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
try {
await configUtils.initConfig(undefined, undefined, "../input", undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(undefined, undefined, undefined, "../input", undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -122,7 +123,7 @@ ava_1.default("load non-local input with invalid repo syntax", async (t) => {
// no filename given, just a repo
const configFile = "octo-org/codeql-config@main";
try {
await configUtils.initConfig(undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(undefined, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -136,7 +137,7 @@ ava_1.default("load non-existent input", async (t) => {
const configFile = "input";
t.false(fs.existsSync(path.join(tmpDir, configFile)));
try {
await configUtils.initConfig(languages, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -200,10 +201,11 @@ ava_1.default("load non-empty input", async (t) => {
codeQLCmd: codeQL.getPath(),
gitHubVersion,
dbLocation: path.resolve(tmpDir, "codeql_databases"),
packs: {},
};
const languages = "javascript";
const configFilePath = createConfigFile(inputFileContents, tmpDir);
const actualConfig = await configUtils.initConfig(languages, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Should exactly equal the object we constructed earlier
t.deepEqual(actualConfig, expectedConfig);
});
@@ -239,7 +241,7 @@ ava_1.default("Default queries are used", async (t) => {
fs.mkdirSync(path.join(tmpDir, "foo"));
const languages = "javascript";
const configFilePath = createConfigFile(inputFileContents, tmpDir);
await configUtils.initConfig(languages, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolve queries was called correctly
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries, [
@@ -282,7 +284,7 @@ ava_1.default("Queries can be specified in config file", async (t) => {
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const config = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries
// and once for `./foo` from the config file.
@@ -315,7 +317,7 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries and once for `./override`,
// but won't be called for './foo' from the config file.
@@ -347,7 +349,7 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolveQueries was called correctly
// It'll be called once for `./workflow-query`,
// but won't be called for the default one since that was disabled
@@ -373,7 +375,7 @@ ava_1.default("Multiple queries can be specified in workflow file, no config fil
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolveQueries was called correctly:
// It'll be called once for the default queries,
// and then once for each of the two queries from the workflow
@@ -412,7 +414,7 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, testQueries, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
// Check resolveQueries was called correctly
// It'll be called once for the default queries,
// once for each of additional1 and additional2,
@@ -451,7 +453,7 @@ ava_1.default("Invalid queries in workflow file handled correctly", async (t) =>
},
});
try {
await configUtils.initConfig(languages, queries, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
t.fail("initConfig did not throw error");
}
catch (err) {
@@ -494,7 +496,7 @@ ava_1.default("API client used when reading remote config", async (t) => {
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
const configFile = "octo-org/codeql-config/config.yaml@main";
const languages = "javascript";
await configUtils.initConfig(languages, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
t.assert(spyGetContents.called);
});
});
@@ -504,7 +506,7 @@ ava_1.default("Remote config handles the case where a directory is provided", as
mockGetContents(dummyResponse);
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(undefined, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(undefined, undefined, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -520,7 +522,7 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
mockGetContents(dummyResponse);
const repoReference = "octo-org/codeql-config/config.yaml@main";
try {
await configUtils.initConfig(undefined, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(undefined, undefined, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -531,8 +533,13 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
ava_1.default("No detected languages", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
mockListLanguages([]);
const codeQL = codeql_1.setCodeQL({
async resolveLanguages() {
return {};
},
});
try {
await configUtils.initConfig(undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -542,16 +549,111 @@ ava_1.default("No detected languages", async (t) => {
});
ava_1.default("Unknown languages", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const languages = "ruby,english";
const languages = "rubbish,english";
try {
await configUtils.initConfig(languages, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(["ruby", "english"])));
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(["rubbish", "english"])));
}
});
});
ava_1.default("Config specifies packages", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeQL = codeql_1.setCodeQL({
async resolveQueries() {
return {
byLanguage: {},
noDeclaredLanguage: {},
multipleDeclaredLanguages: {},
};
},
});
const inputFileContents = `
name: my config
disable-default-queries: true
packs:
- a/b@1.2.3
`;
const configFile = path.join(tmpDir, "codeql-config.yaml");
fs.writeFileSync(configFile, inputFileContents);
const languages = "javascript";
const { packs } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
t.deepEqual(packs, {
[languages_1.Language.javascript]: [
{
packName: "a/b",
version: semver_1.clean("1.2.3"),
},
],
});
});
});
ava_1.default("Config specifies packages for multiple languages", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const codeQL = codeql_1.setCodeQL({
async resolveQueries() {
return {
byLanguage: {
cpp: { "/foo/a.ql": {} },
},
noDeclaredLanguage: {},
multipleDeclaredLanguages: {},
};
},
});
const inputFileContents = `
name: my config
disable-default-queries: true
queries:
- uses: ./foo
packs:
javascript:
- a/b@1.2.3
python:
- c/d@1.2.3
`;
const configFile = path.join(tmpDir, "codeql-config.yaml");
fs.writeFileSync(configFile, inputFileContents);
fs.mkdirSync(path.join(tmpDir, "foo"));
const languages = "javascript,python,cpp";
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example" }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
t.deepEqual(packs, {
[languages_1.Language.javascript]: [
{
packName: "a/b",
version: semver_1.clean("1.2.3"),
},
],
[languages_1.Language.python]: [
{
packName: "c/d",
version: semver_1.clean("1.2.3"),
},
],
});
t.deepEqual(queries, {
cpp: {
builtin: [],
custom: [
{
queries: ["/foo/a.ql"],
searchPath: tmpDir,
},
],
},
javascript: {
builtin: [],
custom: [],
},
python: {
builtin: [],
custom: [],
},
});
});
});
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
ava_1.default(`load invalid input - ${testName}`, async (t) => {
return await util.withTmpDir(async (tmpDir) => {
@@ -569,7 +671,7 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
const inputFile = path.join(tmpDir, configFile);
fs.writeFileSync(inputFile, inputFileContents, "utf8");
try {
await configUtils.initConfig(languages, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -639,4 +741,119 @@ ava_1.default("path sanitisation", (t) => {
// Trailing stars are stripped
t.deepEqual(configUtils.validateAndSanitisePath("foo/**", propertyName, configFile, logging_1.getRunnerLogger(true)), "foo/");
});
/**
* Test macro for ensuring the packs block is valid
*/
function parsePacksMacro(t, packsByLanguage, languages, expected) {
t.deepEqual(configUtils.parsePacksFromConfig(packsByLanguage, languages, "/a/b"), expected);
}
parsePacksMacro.title = (providedTitle) => `Parse Packs: ${providedTitle}`;
/**
* Test macro for testing when the packs block is invalid
*/
function parsePacksErrorMacro(t, packsByLanguage, languages, expected) {
t.throws(() => {
configUtils.parsePacksFromConfig(packsByLanguage, languages, "/a/b");
}, {
message: expected,
});
}
parsePacksErrorMacro.title = (providedTitle) => `Parse Packs Error: ${providedTitle}`;
/**
* Test macro for testing when the packs block is invalid
*/
function invalidPackNameMacro(t, name) {
parsePacksErrorMacro(t, { [languages_1.Language.cpp]: [name] }, [languages_1.Language.cpp], new RegExp(`The configuration file "/a/b" is invalid: property "packs" "${name}" is not a valid pack`));
}
invalidPackNameMacro.title = (_, arg) => `Invalid pack string: ${arg}`;
ava_1.default("no packs", parsePacksMacro, {}, [], {});
ava_1.default("two packs", parsePacksMacro, ["a/b", "c/d@1.2.3"], [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: semver_1.clean("1.2.3") },
],
});
ava_1.default("two packs with spaces", parsePacksMacro, [" a/b ", " c/d@1.2.3 "], [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: semver_1.clean("1.2.3") },
],
});
ava_1.default("two packs with language", parsePacksMacro, {
[languages_1.Language.cpp]: ["a/b", "c/d@1.2.3"],
[languages_1.Language.java]: ["d/e", "f/g@1.2.3"],
}, [languages_1.Language.cpp, languages_1.Language.java, languages_1.Language.csharp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: semver_1.clean("1.2.3") },
],
[languages_1.Language.java]: [
{ packName: "d/e", version: undefined },
{ packName: "f/g", version: semver_1.clean("1.2.3") },
],
});
ava_1.default("no language", parsePacksErrorMacro, ["a/b@1.2.3"], [languages_1.Language.java, languages_1.Language.python], /The configuration file "\/a\/b" is invalid: property "packs" must split packages by language/);
ava_1.default("invalid language", parsePacksErrorMacro, { [languages_1.Language.java]: ["c/d"] }, [languages_1.Language.cpp], /The configuration file "\/a\/b" is invalid: property "packs" has "java", but it is not one of the languages to analyze/);
ava_1.default("not an array", parsePacksErrorMacro, { [languages_1.Language.cpp]: "c/d" }, [languages_1.Language.cpp], /The configuration file "\/a\/b" is invalid: property "packs" must be an array of non-empty strings/);
ava_1.default(invalidPackNameMacro, "c"); // all packs require at least a scope and a name
ava_1.default(invalidPackNameMacro, "c-/d");
ava_1.default(invalidPackNameMacro, "-c/d");
ava_1.default(invalidPackNameMacro, "c/d_d");
ava_1.default(invalidPackNameMacro, "c/d@x");
/**
* Test macro for testing the packs block and the packs input
*/
function parseInputAndConfigMacro(t, packsFromConfig, packsFromInput, languages, expected) {
t.deepEqual(configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b"), expected);
}
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, expected) {
t.throws(() => {
configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b");
}, {
message: expected,
});
}
parseInputAndConfigErrorMacro.title = (providedTitle) => `Parse Packs input and config Error: ${providedTitle}`;
ava_1.default("input only", parseInputAndConfigMacro, {}, " c/d ", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [{ packName: "c/d", version: undefined }],
});
ava_1.default("input only with multiple", parseInputAndConfigMacro, {}, "a/b , c/d@1.2.3", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: "1.2.3" },
],
});
ava_1.default("input only with +", parseInputAndConfigMacro, {}, " + a/b , c/d@1.2.3 ", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: "1.2.3" },
],
});
ava_1.default("config only", parseInputAndConfigMacro, ["a/b", "c/d"], " ", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: undefined },
],
});
ava_1.default("input overrides", parseInputAndConfigMacro, ["a/b", "c/d"], " e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "e/f", version: undefined },
{ packName: "g/h", version: "1.2.3" },
],
});
ava_1.default("input and config", parseInputAndConfigMacro, ["a/b", "c/d"], " +e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
[languages_1.Language.cpp]: [
{ packName: "e/f", version: undefined },
{ packName: "g/h", version: "1.2.3" },
{ packName: "a/b", version: undefined },
{ packName: "c/d", version: undefined },
],
});
ava_1.default("input with no language", parseInputAndConfigErrorMacro, {}, "c/d", [], /No languages specified/);
ava_1.default("input with two languages", parseInputAndConfigErrorMacro, {}, "c/d", [languages_1.Language.cpp, languages_1.Language.csharp], /multi-language analysis/);
ava_1.default("input with + only", parseInputAndConfigErrorMacro, {}, " + ", [languages_1.Language.cpp], /remove the '\+'/);
ava_1.default("input with invalid pack name", parseInputAndConfigErrorMacro, {}, " xxx", [languages_1.Language.cpp], /"xxx" is not a valid pack/);
// errors
// input w invalid pack name
//# sourceMappingURL=config-utils.test.js.map

File diff suppressed because one or more lines are too long

3
lib/count-loc.js generated
View File

@@ -12,6 +12,7 @@ const linguistToMetrics = {
java: languages_1.Language.java,
javascript: languages_1.Language.javascript,
python: languages_1.Language.python,
ruby: languages_1.Language.ruby,
typescript: languages_1.Language.javascript,
};
const nameToLinguist = Object.entries(linguistToMetrics).reduce((obj, [key, name]) => {
@@ -35,6 +36,8 @@ function getIdPrefix(language) {
return "js";
case languages_1.Language.python:
return "py";
case languages_1.Language.ruby:
return "rb";
default:
util_1.assertNever(language);
}

View File

@@ -1 +1 @@
{"version":3,"file":"count-loc.js","sourceRoot":"","sources":["../src/count-loc.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"count-loc.js","sourceRoot":"","sources":["../src/count-loc.ts"],"names":[],"mappings":"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"}

12
lib/count-loc.test.js generated
View File

@@ -21,13 +21,19 @@ ava_1.default("ensure lines of code works for cpp and js", async (t) => {
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.cpp, languages_1.Language.javascript], logging_1.getRunnerLogger(true));
t.deepEqual(results, {
cpp: 6,
javascript: 3,
javascript: 9,
});
});
ava_1.default("ensure lines of code works for csharp", async (t) => {
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.csharp], logging_1.getRunnerLogger(true));
t.deepEqual(results, {
csharp: 10,
});
});
ava_1.default("ensure lines of code can handle undefined language", async (t) => {
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.javascript, languages_1.Language.python, "hucairz"], logging_1.getRunnerLogger(true));
t.deepEqual(results, {
javascript: 3,
javascript: 9,
python: 5,
});
});
@@ -54,7 +60,7 @@ ava_1.default("ensure lines of code can handle empty includes", async (t) => {
ava_1.default("ensure lines of code can handle exclude", async (t) => {
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], ["**/*.py"], [languages_1.Language.javascript, languages_1.Language.python], logging_1.getRunnerLogger(true));
t.deepEqual(results, {
javascript: 3,
javascript: 9,
});
});
//# sourceMappingURL=count-loc.test.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"count-loc.test.js","sourceRoot":"","sources":["../src/count-loc.test.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"count-loc.test.js","sourceRoot":"","sources":["../src/count-loc.test.ts"],"names":[],"mappings":"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"}

71
lib/database-upload.js generated Normal file
View File

@@ -0,0 +1,71 @@
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const actionsUtil = __importStar(require("./actions-util"));
const api_client_1 = require("./api-client");
const codeql_1 = require("./codeql");
const util = __importStar(require("./util"));
async function uploadDatabases(repositoryNwo, config, apiDetails, logger) {
if (actionsUtil.getRequiredInput("upload-database") !== "true") {
logger.debug("Database upload disabled in workflow. Skipping upload.");
return;
}
// Do nothing when not running against github.com
if (config.gitHubVersion.type !== util.GitHubVariant.DOTCOM) {
logger.debug("Not running against github.com. Skipping upload.");
return;
}
if (!(await actionsUtil.isAnalyzingDefaultBranch())) {
// We only want to upload a database if we are analyzing the default branch.
logger.debug("Not analyzing default branch. Skipping upload.");
return;
}
const client = api_client_1.getApiClient(apiDetails);
try {
await client.request("GET /repos/:owner/:repo/code-scanning/databases", {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
});
}
catch (e) {
if (util.isHTTPError(e) && e.status === 404) {
logger.debug("Repository is not opted in to database uploads. Skipping upload.");
}
else {
console.log(e);
logger.info(`Skipping database upload due to unknown error: ${e}`);
}
return;
}
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
for (const language of config.languages) {
// Bundle the database up into a single zip file
const databasePath = util.getCodeQLDatabasePath(config, language);
const databaseBundlePath = `${databasePath}.zip`;
await codeql.databaseBundle(databasePath, databaseBundlePath);
// Upload the database bundle
const payload = fs.readFileSync(databaseBundlePath);
try {
await client.request(`PUT /repos/:owner/:repo/code-scanning/databases/${language}`, {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
});
logger.debug(`Successfully uploaded database for ${language}`);
}
catch (e) {
console.log(e);
// Log a warning but don't fail the workflow
logger.warning(`Failed to upload database for ${language}: ${e}`);
}
}
}
exports.uploadDatabases = uploadDatabases;
//# sourceMappingURL=database-upload.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"database-upload.js","sourceRoot":"","sources":["../src/database-upload.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AAEzB,4DAA8C;AAC9C,6CAA8D;AAC9D,qCAAqC;AAIrC,6CAA+B;AAExB,KAAK,UAAU,eAAe,CACnC,aAA4B,EAC5B,MAAc,EACd,UAA4B,EAC5B,MAAc;IAEd,IAAI,WAAW,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,KAAK,MAAM,EAAE;QAC9D,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACvE,OAAO;KACR;IAED,iDAAiD;IACjD,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;QAC3D,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACjE,OAAO;KACR;IAED,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,wBAAwB,EAAE,CAAC,EAAE;QACnD,4EAA4E;QAC5E,MAAM,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC/D,OAAO;KACR;IAED,MAAM,MAAM,GAAG,yBAAY,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI;QACF,MAAM,MAAM,CAAC,OAAO,CAAC,iDAAiD,EAAE;YACtE,KAAK,EAAE,aAAa,CAAC,KAAK;YAC1B,IAAI,EAAE,aAAa,CAAC,IAAI;SACzB,CAAC,CAAC;KACJ;IAAC,OAAO,CAAC,EAAE;QACV,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE;YAC3C,MAAM,CAAC,KAAK,CACV,kEAAkE,CACnE,CAAC;SACH;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,EAAE,CAAC,CAAC;SACpE;QACD,OAAO;KACR;IAED,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAClE,MAAM,kBAAkB,GAAG,GAAG,YAAY,MAAM,CAAC;QACjD,MAAM,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QAE9D,6BAA6B;QAC7B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;QACpD,IAAI;YACF,MAAM,MAAM,CAAC,OAAO,CAClB,mDAAmD,QAAQ,EAAE,EAC7D;gBACE,KAAK,EAAE,aAAa,CAAC,KAAK;gBAC1B,IAAI,EAAE,aAAa,CAAC,IAAI;gBACxB,IAAI,EAAE,OAAO;aACd,CACF,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;SAChE;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,4CAA4C;YAC5C,MAAM,CAAC,OAAO,CAAC,iCAAiC,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;SACnE;KACF;AACH,CAAC;AAlED,0CAkEC"}

226
lib/database-upload.test.js generated Normal file
View File

@@ -0,0 +1,226 @@
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const github = __importStar(require("@actions/github"));
const ava_1 = __importDefault(require("ava"));
const sinon_1 = __importDefault(require("sinon"));
const actionsUtil = __importStar(require("./actions-util"));
const apiClient = __importStar(require("./api-client"));
const codeql_1 = require("./codeql");
const database_upload_1 = require("./database-upload");
const languages_1 = require("./languages");
const testing_utils_1 = require("./testing-utils");
const util_1 = require("./util");
testing_utils_1.setupTests(ava_1.default);
ava_1.default.beforeEach(() => {
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
});
const testRepoName = { owner: "github", repo: "example" };
const testApiDetails = {
auth: "1234",
url: "https://github.com",
};
function getTestConfig(tmpDir) {
return {
languages: [languages_1.Language.javascript],
queries: {},
pathsIgnore: [],
paths: [],
originalUserInput: {},
tempDir: tmpDir,
toolCacheDir: tmpDir,
codeQLCmd: "foo",
gitHubVersion: { type: util_1.GitHubVariant.DOTCOM },
dbLocation: tmpDir,
packs: {},
};
}
function getRecordingLogger(messages) {
return {
debug: (message) => {
messages.push({ type: "debug", message });
console.debug(message);
},
info: (message) => {
messages.push({ type: "info", message });
console.info(message);
},
warning: (message) => {
messages.push({ type: "warning", message });
console.warn(message);
},
error: (message) => {
messages.push({ type: "error", message });
console.error(message);
},
isDebug: () => true,
startGroup: () => undefined,
endGroup: () => undefined,
};
}
function mockHttpRequests(optInStatusCode, databaseUploadStatusCode) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
const requestSpy = sinon_1.default.stub(client, "request");
const optInSpy = requestSpy.withArgs("GET /repos/:owner/:repo/code-scanning/databases");
if (optInStatusCode < 300) {
optInSpy.resolves(undefined);
}
else {
optInSpy.throws(new util_1.HTTPError("some error message", optInStatusCode));
}
if (databaseUploadStatusCode !== undefined) {
const databaseUploadSpy = requestSpy.withArgs("PUT /repos/:owner/:repo/code-scanning/databases/javascript");
if (databaseUploadStatusCode < 300) {
databaseUploadSpy.resolves(undefined);
}
else {
databaseUploadSpy.throws(new util_1.HTTPError("some error message", databaseUploadStatusCode));
}
}
sinon_1.default.stub(apiClient, "getApiClient").value(() => client);
}
ava_1.default("Abort database upload if 'upload-database' input set to false", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("false");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Database upload disabled in workflow. Skipping upload.") !== undefined);
});
});
ava_1.default("Abort database upload if running against GHES", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
const config = getTestConfig(tmpDir);
config.gitHubVersion = { type: util_1.GitHubVariant.GHES, version: "3.0" };
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, config, testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Not running against github.com. Skipping upload.") !== undefined);
});
});
ava_1.default("Abort database upload if running against GHAE", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
const config = getTestConfig(tmpDir);
config.gitHubVersion = { type: util_1.GitHubVariant.GHAE };
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, config, testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Not running against github.com. Skipping upload.") !== undefined);
});
});
ava_1.default("Abort database upload if not analyzing default branch", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(false);
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Not analyzing default branch. Skipping upload.") !== undefined);
});
});
ava_1.default("Abort database upload if opt-in request returns 404", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(404);
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message ===
"Repository is not opted in to database uploads. Skipping upload.") !== undefined);
});
});
ava_1.default("Abort database upload if opt-in request fails with something other than 404", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(500);
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "info" &&
v.message ===
"Skipping database upload due to unknown error: Error: some error message") !== undefined);
});
});
ava_1.default("Don't crash if uploading a database fails", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(204, 500);
codeql_1.setCodeQL({
async databaseBundle(_, outputFilePath) {
fs.writeFileSync(outputFilePath, "");
},
});
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "warning" &&
v.message ===
"Failed to upload database for javascript: Error: some error message") !== undefined);
});
});
ava_1.default("Successfully uploading a database", async (t) => {
await util_1.withTmpDir(async (tmpDir) => {
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
sinon_1.default
.stub(actionsUtil, "getRequiredInput")
.withArgs("upload-database")
.returns("true");
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
mockHttpRequests(204, 201);
codeql_1.setCodeQL({
async databaseBundle(_, outputFilePath) {
fs.writeFileSync(outputFilePath, "");
},
});
const loggedMessages = [];
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
t.assert(loggedMessages.find((v) => v.type === "debug" &&
v.message === "Successfully uploaded database for javascript") !== undefined);
});
});
//# sourceMappingURL=database-upload.test.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
{
"bundleVersion": "codeql-bundle-20210517"
"bundleVersion": "codeql-bundle-20210622"
}

28
lib/fingerprints.js generated
View File

@@ -16,6 +16,7 @@ const tab = "\t".charCodeAt(0);
const space = " ".charCodeAt(0);
const lf = "\n".charCodeAt(0);
const cr = "\r".charCodeAt(0);
const EOF = 65535;
const BLOCK_SIZE = 100;
const MOD = long_1.default.fromInt(37); // L
// Compute the starting point for the hash mod
@@ -36,9 +37,9 @@ function computeFirstMod() {
* the hashes of the lines near the end of the file.
*
* @param callback function that is called with the line number (1-based) and hash for every line
* @param input The file's contents
* @param filepath The path to the file to hash
*/
function hash(callback, input) {
async function hash(callback, filepath) {
// A rolling view in to the input
const window = Array(BLOCK_SIZE).fill(0);
// If the character in the window is the start of a new line
@@ -82,12 +83,11 @@ function hash(callback, input) {
// as we go. Once we reach a point in the window again then we've processed
// BLOCK_SIZE characters and if the last character at this point in the window
// was the start of a line then we should output the hash for that line.
for (let i = 0, len = input.length; i <= len; i++) {
let current = i === len ? 65535 : input.charCodeAt(i);
const processCharacter = function (current) {
// skip tabs, spaces, and line feeds that come directly after a carriage return
if (current === space || current === tab || (prevCR && current === lf)) {
prevCR = false;
continue;
return;
}
// replace CR with LF
if (current === cr) {
@@ -109,7 +109,14 @@ function hash(callback, input) {
lineStart = true;
}
updateHash(current);
};
const readStream = fs.createReadStream(filepath, "utf8");
for await (const data of readStream) {
for (let i = 0; i < data.length; ++i) {
processCharacter(data.charCodeAt(i));
}
}
processCharacter(EOF);
// Flush the remaining lines
for (let i = 0; i < BLOCK_SIZE; i++) {
if (lineNumbers[index] !== -1) {
@@ -206,8 +213,8 @@ function resolveUriToFile(location, artifacts, checkoutPath, logger) {
exports.resolveUriToFile = resolveUriToFile;
// Compute fingerprints for results in the given sarif file
// and return an updated sarif file contents.
function addFingerprints(sarifContents, checkoutPath, logger) {
var _a, _b;
async function addFingerprints(sarifContents, checkoutPath, logger) {
var _a, _b, _c, _d, _e;
const sarif = JSON.parse(sarifContents);
// Gather together results for the same file and construct
// callbacks to accept hashes for that file and update the location
@@ -222,6 +229,10 @@ function addFingerprints(sarifContents, checkoutPath, logger) {
logger.debug(`Unable to compute fingerprint for invalid location: ${JSON.stringify(primaryLocation)}`);
continue;
}
if (((_e = (_d = (_c = primaryLocation) === null || _c === void 0 ? void 0 : _c.physicalLocation) === null || _d === void 0 ? void 0 : _d.region) === null || _e === void 0 ? void 0 : _e.startLine) === undefined) {
// Locations without a line number are unlikely to be source files
continue;
}
const filepath = resolveUriToFile(primaryLocation.physicalLocation.artifactLocation, artifacts, checkoutPath, logger);
if (!filepath) {
continue;
@@ -240,8 +251,7 @@ function addFingerprints(sarifContents, checkoutPath, logger) {
c(lineNumber, hashValue);
}
};
const fileContents = fs.readFileSync(filepath).toString();
hash(teeCallback, fileContents);
await hash(teeCallback, filepath);
}
return JSON.stringify(sarif);
}

File diff suppressed because one or more lines are too long

View File

@@ -16,28 +16,33 @@ const ava_1 = __importDefault(require("ava"));
const fingerprints = __importStar(require("./fingerprints"));
const logging_1 = require("./logging");
const testing_utils_1 = require("./testing-utils");
const util = __importStar(require("./util"));
testing_utils_1.setupTests(ava_1.default);
function testHash(t, input, expectedHashes) {
let index = 0;
const callback = function (lineNumber, hash) {
t.is(lineNumber, index + 1);
t.is(hash, expectedHashes[index]);
index++;
};
fingerprints.hash(callback, input);
t.is(index, input.split(/\r\n|\r|\n/).length);
async function testHash(t, input, expectedHashes) {
await util.withTmpDir(async (tmpDir) => {
const tmpFile = path.resolve(tmpDir, "testfile");
fs.writeFileSync(tmpFile, input);
let index = 0;
const callback = function (lineNumber, hash) {
t.is(lineNumber, index + 1);
t.is(hash, expectedHashes[index]);
index++;
};
await fingerprints.hash(callback, tmpFile);
t.is(index, input.split(/\r\n|\r|\n/).length);
});
}
ava_1.default("hash", (t) => {
ava_1.default("hash", async (t) => {
// Try empty file
testHash(t, "", ["c129715d7a2bc9a3:1"]);
await testHash(t, "", ["c129715d7a2bc9a3:1"]);
// Try various combinations of newline characters
testHash(t, " a\nb\n \t\tc\n d", [
await testHash(t, " a\nb\n \t\tc\n d", [
"271789c17abda88f:1",
"54703d4cd895b18:1",
"180aee12dab6264:1",
"a23a3dc5e078b07b:1",
]);
testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End", [
await testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End", [
"8b7cf3e952e7aeb2:1",
"b1ae1287ec4718d9:1",
"bff680108adb0fcc:1",
@@ -45,7 +50,7 @@ ava_1.default("hash", (t) => {
"b86d3392aea1be30:1",
"e6ceba753e1a442:1",
]);
testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End\n", [
await testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End\n", [
"e9496ae3ebfced30:1",
"fb7c023a8b9ccb3f:1",
"ce8ba1a563dcdaca:1",
@@ -54,7 +59,7 @@ ava_1.default("hash", (t) => {
"c8e28b0b4002a3a0:1",
"c129715d7a2bc9a3:1",
]);
testHash(t, " hello; \t\nworld!!!\r\r\r \t\tGreetings\r End\r", [
await testHash(t, " hello; \t\nworld!!!\r\r\r \t\tGreetings\r End\r", [
"e9496ae3ebfced30:1",
"fb7c023a8b9ccb3f:1",
"ce8ba1a563dcdaca:1",
@@ -63,7 +68,7 @@ ava_1.default("hash", (t) => {
"c8e28b0b4002a3a0:1",
"c129715d7a2bc9a3:1",
]);
testHash(t, " hello; \t\r\nworld!!!\r\n\r\n\r\n \t\tGreetings\r\n End\r\n", [
await testHash(t, " hello; \t\r\nworld!!!\r\n\r\n\r\n \t\tGreetings\r\n End\r\n", [
"e9496ae3ebfced30:1",
"fb7c023a8b9ccb3f:1",
"ce8ba1a563dcdaca:1",
@@ -72,7 +77,7 @@ ava_1.default("hash", (t) => {
"c8e28b0b4002a3a0:1",
"c129715d7a2bc9a3:1",
]);
testHash(t, " hello; \t\nworld!!!\r\n\n\r \t\tGreetings\r End\r\n", [
await testHash(t, " hello; \t\nworld!!!\r\n\n\r \t\tGreetings\r End\r\n", [
"e9496ae3ebfced30:1",
"fb7c023a8b9ccb3f:1",
"ce8ba1a563dcdaca:1",
@@ -82,7 +87,7 @@ ava_1.default("hash", (t) => {
"c129715d7a2bc9a3:1",
]);
// Try repeating line that will generate identical hashes
testHash(t, "Lorem ipsum dolor sit amet.\n".repeat(10), [
await testHash(t, "Lorem ipsum dolor sit amet.\n".repeat(10), [
"a7f2ff13bc495cf2:1",
"a7f2ff13bc495cf2:2",
"a7f2ff13bc495cf2:3",
@@ -95,7 +100,7 @@ ava_1.default("hash", (t) => {
"cc97dc7b1d7d8f7b:1",
"c129715d7a2bc9a3:1",
]);
testHash(t, "x = 2\nx = 1\nprint(x)\nx = 3\nprint(x)\nx = 4\nprint(x)\n", [
await testHash(t, "x = 2\nx = 1\nprint(x)\nx = 3\nprint(x)\nx = 4\nprint(x)\n", [
"e54938cc54b302f1:1",
"bb609acbe9138d60:1",
"1131fd5871777f34:1",
@@ -150,7 +155,7 @@ ava_1.default("resolveUriToFile", (t) => {
t.is(testResolveUriToFile(dirpath, undefined, []), undefined);
t.is(testResolveUriToFile(`file://${dirpath}`, undefined, []), undefined);
});
ava_1.default("addFingerprints", (t) => {
ava_1.default("addFingerprints", async (t) => {
// Run an end-to-end test on a test file
let input = fs
.readFileSync(`${__dirname}/../src/testdata/fingerprinting.input.sarif`)
@@ -163,9 +168,9 @@ ava_1.default("addFingerprints", (t) => {
expected = JSON.stringify(JSON.parse(expected));
// The URIs in the SARIF files resolve to files in the testdata directory
const checkoutPath = path.normalize(`${__dirname}/../src/testdata`);
t.deepEqual(fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
t.deepEqual(await fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
});
ava_1.default("missingRegions", (t) => {
ava_1.default("missingRegions", async (t) => {
// Run an end-to-end test on a test file
let input = fs
.readFileSync(`${__dirname}/../src/testdata/fingerprinting2.input.sarif`)
@@ -178,6 +183,6 @@ ava_1.default("missingRegions", (t) => {
expected = JSON.stringify(JSON.parse(expected));
// The URIs in the SARIF files resolve to files in the testdata directory
const checkoutPath = path.normalize(`${__dirname}/../src/testdata`);
t.deepEqual(fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
t.deepEqual(await fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
});
//# sourceMappingURL=fingerprints.test.js.map

File diff suppressed because one or more lines are too long

38
lib/init-action.js generated
View File

@@ -8,24 +8,26 @@ var __importStar = (this && this.__importStar) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const actionsUtil = __importStar(require("./actions-util"));
const actions_util_1 = require("./actions-util");
const init_1 = require("./init");
const languages_1 = require("./languages");
const logging_1 = require("./logging");
const repository_1 = require("./repository");
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
async function sendSuccessStatusReport(startedAt, config, toolsVersion) {
var _a;
const statusReportBase = await actionsUtil.createStatusReportBase("init", "success", startedAt);
const statusReportBase = await actions_util_1.createStatusReportBase("init", "success", startedAt);
const languages = config.languages.join(",");
const workflowLanguages = actionsUtil.getOptionalInput("languages");
const workflowLanguages = actions_util_1.getOptionalInput("languages");
const paths = (config.originalUserInput.paths || []).join(",");
const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join(",");
const disableDefaultQueries = config.originalUserInput["disable-default-queries"]
? languages
: "";
const queries = [];
let queriesInput = (_a = actionsUtil.getOptionalInput("queries")) === null || _a === void 0 ? void 0 : _a.trim();
let queriesInput = (_a = actions_util_1.getOptionalInput("queries")) === null || _a === void 0 ? void 0 : _a.trim();
if (queriesInput === undefined || queriesInput.startsWith("+")) {
queries.push(...(config.originalUserInput.queries || []).map((q) => q.uses));
}
@@ -43,36 +45,36 @@ async function sendSuccessStatusReport(startedAt, config, toolsVersion) {
paths_ignore: pathsIgnore,
disable_default_queries: disableDefaultQueries,
queries: queries.join(","),
tools_input: actionsUtil.getOptionalInput("tools") || "",
tools_input: actions_util_1.getOptionalInput("tools") || "",
tools_resolved_version: toolsVersion,
};
await actionsUtil.sendStatusReport(statusReport);
await actions_util_1.sendStatusReport(statusReport);
}
async function run() {
const startedAt = new Date();
const logger = logging_1.getActionsLogger();
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
let config;
let codeql;
let toolsVersion;
const apiDetails = {
auth: actionsUtil.getRequiredInput("token"),
externalRepoAuth: actionsUtil.getOptionalInput("external-repository-token"),
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
auth: actions_util_1.getRequiredInput("token"),
externalRepoAuth: actions_util_1.getOptionalInput("external-repository-token"),
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
};
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
util_1.checkGitHubVersionInRange(gitHubVersion, "actions", logger);
util_1.checkGitHubVersionInRange(gitHubVersion, logger, util_1.Mode.actions);
try {
actionsUtil.prepareLocalRunEnvironment();
const workflowErrors = await actionsUtil.validateWorkflow();
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "starting", startedAt, workflowErrors)))) {
const workflowErrors = await actions_util_1.validateWorkflow();
if (!(await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "starting", startedAt, workflowErrors)))) {
return;
}
const initCodeQLResult = await init_1.initCodeQL(actionsUtil.getOptionalInput("tools"), apiDetails, actionsUtil.getTemporaryDirectory(), actionsUtil.getToolCacheDirectory(), "actions", gitHubVersion.type, logger);
const initCodeQLResult = await init_1.initCodeQL(actions_util_1.getOptionalInput("tools"), apiDetails, actions_util_1.getTemporaryDirectory(), actions_util_1.getToolCacheDirectory(), gitHubVersion.type, logger);
codeql = initCodeQLResult.codeql;
toolsVersion = initCodeQLResult.toolsVersion;
config = await init_1.initConfig(actionsUtil.getOptionalInput("languages"), actionsUtil.getOptionalInput("queries"), actionsUtil.getOptionalInput("config-file"), actionsUtil.getOptionalInput("db-location"), repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), actionsUtil.getTemporaryDirectory(), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"), gitHubVersion, apiDetails, logger);
config = await init_1.initConfig(actions_util_1.getOptionalInput("languages"), actions_util_1.getOptionalInput("queries"), actions_util_1.getOptionalInput("packs"), actions_util_1.getOptionalInput("config-file"), actions_util_1.getOptionalInput("db-location"), repository_1.parseRepositoryNwo(util_1.getRequiredEnvParam("GITHUB_REPOSITORY")), actions_util_1.getTemporaryDirectory(), util_1.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, util_1.getRequiredEnvParam("GITHUB_WORKSPACE"), gitHubVersion, apiDetails, logger);
if (config.languages.includes(languages_1.Language.python) &&
actionsUtil.getRequiredInput("setup-python-dependencies") === "true") {
actions_util_1.getRequiredInput("setup-python-dependencies") === "true") {
try {
await init_1.installPythonDeps(codeql, logger);
}
@@ -84,7 +86,7 @@ async function run() {
catch (e) {
core.setFailed(e.message);
console.log(e);
await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "aborted", startedAt, e.message));
await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "aborted", startedAt, e.message));
return;
}
try {
@@ -111,7 +113,7 @@ async function run() {
catch (error) {
core.setFailed(error.message);
console.log(error);
await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "failure", startedAt, error.message, error.stack));
await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "failure", startedAt, error.message, error.stack));
return;
}
await sendSuccessStatusReport(startedAt, config, toolsVersion);

View File

@@ -1 +1 @@
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}

8
lib/init.js generated
View File

@@ -16,17 +16,17 @@ const codeql_1 = require("./codeql");
const configUtils = __importStar(require("./config-utils"));
const tracer_config_1 = require("./tracer-config");
const util = __importStar(require("./util"));
async function initCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, variant, logger) {
async function initCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger) {
logger.startGroup("Setup CodeQL tools");
const { codeql, toolsVersion } = await codeql_1.setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, mode, variant, logger);
const { codeql, toolsVersion } = await codeql_1.setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger);
await codeql.printVersion();
logger.endGroup();
return { codeql, toolsVersion };
}
exports.initCodeQL = initCodeQL;
async function initConfig(languagesInput, queriesInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
async function initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
logger.startGroup("Load language configuration");
const config = await configUtils.initConfig(languagesInput, queriesInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
analysisPaths.printPathFiltersWarning(config, logger);
logger.endGroup();
return config;

View File

@@ -1 +1 @@
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}

1
lib/languages.js generated
View File

@@ -9,6 +9,7 @@ var Language;
Language["java"] = "java";
Language["javascript"] = "javascript";
Language["python"] = "python";
Language["ruby"] = "ruby";
})(Language = exports.Language || (exports.Language = {}));
// Additional names for languages
const LANGUAGE_ALIASES = {

View File

@@ -1 +1 @@
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,IAAY,QAOX;AAPD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;AACnB,CAAC,EAPW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAOnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CACL,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,KAAK,IAAI;YACxD,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAC5B,CAAC;AACJ,CAAC;AAND,4CAMC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,IAAY,QAQX;AARD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;AACf,CAAC,EARW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAQnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CACL,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,KAAK,IAAI;YACxD,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAC5B,CAAC;AACJ,CAAC;AAND,4CAMC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}

18
lib/runner.js generated
View File

@@ -21,8 +21,12 @@ const logging_1 = require("./logging");
const repository_1 = require("./repository");
const upload_lib = __importStar(require("./upload-lib"));
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
const program = new commander_1.Command();
program.version("0.0.1");
program.version(pkg.version).hook("preAction", () => {
util_1.initializeEnvironment(util_1.Mode.runner, pkg.version);
});
function getTempDir(userInput) {
const tempDir = path.join(userInput || process.cwd(), "codeql-runner");
if (!fs.existsSync(tempDir)) {
@@ -86,6 +90,12 @@ program
.option("--github-auth-stdin", "Read GitHub Apps token or personal access token from stdin.")
.option("--languages <languages>", "Comma-separated list of languages to analyze. Otherwise detects and analyzes all supported languages from the repo.")
.option("--queries <queries>", "Comma-separated list of additional queries to run. This overrides the same setting in a configuration file.")
.option("--packs <packs>", `[Experimental] Comma-separated list of packs to run. Reference a pack in the format scope/name[@version]. If version is not
specified, then the latest version of the pack is used. By default, this overrides the same setting in a
configuration file; prefix with "+" to use both sets of packs.
This option is only available in single-language analyses. To use packs in multi-language
analyses, you must specify packs in the codeql-config.yml file.`)
.option("--config-file <file>", "Path to config file.")
.option("--codeql-path <path>", "Path to a copy of the CodeQL CLI executable to use. Otherwise downloads a copy.")
.option("--temp-dir <dir>", 'Directory to use for temporary files. Default is "./codeql-runner".')
@@ -110,15 +120,15 @@ program
url: util_1.parseGitHubUrl(cmd.githubUrl),
};
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
util_1.checkGitHubVersionInRange(gitHubVersion, "runner", logger);
util_1.checkGitHubVersionInRange(gitHubVersion, logger, util_1.Mode.runner);
let codeql;
if (cmd.codeqlPath !== undefined) {
codeql = codeql_1.getCodeQL(cmd.codeqlPath);
}
else {
codeql = (await init_1.initCodeQL(undefined, apiDetails, tempDir, toolsDir, "runner", gitHubVersion.type, logger)).codeql;
codeql = (await init_1.initCodeQL(undefined, apiDetails, tempDir, toolsDir, gitHubVersion.type, logger)).codeql;
}
const config = await init_1.initConfig(cmd.languages, cmd.queries, cmd.configFile, undefined, repository_1.parseRepositoryNwo(cmd.repository), tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), gitHubVersion, apiDetails, logger);
const config = await init_1.initConfig(cmd.languages, cmd.queries, cmd.packs, cmd.configFile, undefined, repository_1.parseRepositoryNwo(cmd.repository), tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), gitHubVersion, apiDetails, logger);
const tracerConfig = await init_1.runInit(codeql, config);
if (tracerConfig === undefined) {
return;

File diff suppressed because one or more lines are too long

27
lib/toolcache.js generated
View File

@@ -15,6 +15,8 @@ const io = __importStar(require("@actions/io"));
const actionsToolcache = __importStar(require("@actions/tool-cache"));
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
const semver = __importStar(require("semver"));
const uuid_1 = require("uuid");
const util_1 = require("./util");
/*
* This file acts as an interface to the functionality of the actions toolcache.
* That library is not safe to use outside of actions as it makes assumptions about
@@ -34,8 +36,8 @@ const semver = __importStar(require("semver"));
* @param logger logger to use
* @returns path to the destination directory
*/
async function extractTar(file, mode, tempDir, logger) {
if (mode === "actions") {
async function extractTar(file, tempDir, logger) {
if (util_1.isActions()) {
return await actionsToolcache.extractTar(file);
}
else {
@@ -94,8 +96,8 @@ exports.extractTar = extractTar;
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
async function cacheDir(sourceDir, tool, version, mode, toolCacheDir, logger) {
if (mode === "actions") {
async function cacheDir(sourceDir, tool, version, toolCacheDir, logger) {
if (util_1.isActions()) {
return await actionsToolcache.cacheDir(sourceDir, tool, version);
}
else {
@@ -132,8 +134,8 @@ exports.cacheDir = cacheDir;
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
function find(toolName, versionSpec, mode, toolCacheDir, logger) {
if (mode === "actions") {
function find(toolName, versionSpec, toolCacheDir, logger) {
if (util_1.isActions()) {
return actionsToolcache.find(toolName, versionSpec);
}
else {
@@ -147,7 +149,7 @@ function find(toolName, versionSpec, mode, toolCacheDir, logger) {
const arch = os.arch();
// attempt to resolve an explicit version
if (!isExplicitVersion(versionSpec, logger)) {
const localVersions = findAllVersions(toolName, mode, toolCacheDir, logger);
const localVersions = findAllVersions(toolName, toolCacheDir, logger);
const match = evaluateVersions(localVersions, versionSpec, logger);
versionSpec = match;
}
@@ -175,12 +177,11 @@ exports.find = find;
* Also see findAllVersions function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
*
* @param toolName name of the tool
* @param mode should run the actions or runner implementation
* @param toolCacheDir path to the tool cache directory
* @param logger logger to use
*/
function findAllVersions(toolName, mode, toolCacheDir, logger) {
if (mode === "actions") {
function findAllVersions(toolName, toolCacheDir, logger) {
if (util_1.isActions()) {
return actionsToolcache.findAllVersions(toolName);
}
else {
@@ -204,6 +205,12 @@ function findAllVersions(toolName, mode, toolCacheDir, logger) {
}
}
exports.findAllVersions = findAllVersions;
async function downloadTool(url, tempDir, headers) {
const dest = path.join(tempDir, uuid_1.v4());
const finalHeaders = Object.assign({ "User-Agent": "CodeQL Action" }, headers);
return await actionsToolcache.downloadTool(url, dest, undefined, finalHeaders);
}
exports.downloadTool = downloadTool;
function createExtractFolder(tempDir) {
// create a temp dir
const dest = path.join(tempDir, "toolcache-temp");

File diff suppressed because one or more lines are too long

View File

@@ -31,6 +31,7 @@ function getTestConfig(tmpDir) {
codeQLCmd: "",
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
dbLocation: path.resolve(tmpDir, "codeql_databases"),
packs: {},
};
}
// A very minimal setup

File diff suppressed because one or more lines are too long

22
lib/upload-lib.js generated
View File

@@ -74,7 +74,7 @@ function getAutomationID(category, analysis_key, environment) {
}
// Upload the given payload.
// If the request fails then this will retry a small number of times.
async function uploadPayload(payload, repositoryNwo, apiDetails, mode, logger) {
async function uploadPayload(payload, repositoryNwo, apiDetails, logger) {
logger.info("Uploading results");
// If in test mode we don't want to upload the results
const testMode = process.env["TEST_MODE"] === "true" || false;
@@ -82,7 +82,7 @@ async function uploadPayload(payload, repositoryNwo, apiDetails, mode, logger) {
return;
}
const client = api.getApiClient(apiDetails);
const reqURL = mode === "actions"
const reqURL = util.isActions()
? "PUT /repos/:owner/:repo/code-scanning/analysis"
: "POST /repos/:owner/:repo/code-scanning/sarifs";
const response = await client.request(reqURL, {
@@ -116,14 +116,14 @@ exports.findSarifFilesInDir = findSarifFilesInDir;
// depending on what the path happens to refer to.
// Returns true iff the upload occurred and succeeded
async function uploadFromActions(sarifPath, gitHubVersion, apiDetails, logger) {
return await uploadFiles(getSarifFilePaths(sarifPath), repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(), await actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getOptionalInput("category"), actionsUtil.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), gitHubVersion, apiDetails, "actions", logger);
return await uploadFiles(getSarifFilePaths(sarifPath), repository_1.parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(), await actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getOptionalInput("category"), util.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), gitHubVersion, apiDetails, logger);
}
exports.uploadFromActions = uploadFromActions;
// Uploads a single sarif file or a directory of sarif files
// depending on what the path happens to refer to.
// Returns true iff the upload occurred and succeeded
async function uploadFromRunner(sarifPath, repositoryNwo, commitOid, ref, category, checkoutPath, gitHubVersion, apiDetails, logger) {
return await uploadFiles(getSarifFilePaths(sarifPath), repositoryNwo, commitOid, ref, undefined, category, undefined, undefined, checkoutPath, undefined, gitHubVersion, apiDetails, "runner", logger);
return await uploadFiles(getSarifFilePaths(sarifPath), repositoryNwo, commitOid, ref, undefined, category, undefined, undefined, checkoutPath, undefined, gitHubVersion, apiDetails, logger);
}
exports.uploadFromRunner = uploadFromRunner;
function getSarifFilePaths(sarifPath) {
@@ -186,8 +186,8 @@ function validateSarifFileSchema(sarifFilePath, logger) {
exports.validateSarifFileSchema = validateSarifFileSchema;
// buildPayload constructs a map ready to be uploaded to the API from the given
// parameters, respecting the current mode and target GitHub instance version.
function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion, mode) {
if (mode === "actions") {
function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion) {
if (util.isActions()) {
const payloadObj = {
commit_oid: commitOid,
ref,
@@ -227,10 +227,10 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
exports.buildPayload = buildPayload;
// Uploads the given set of sarif files.
// Returns true iff the upload occurred and succeeded
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, checkoutPath, environment, gitHubVersion, apiDetails, mode, logger) {
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, checkoutPath, environment, gitHubVersion, apiDetails, logger) {
logger.startGroup("Uploading results");
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
if (mode === "actions") {
if (util.isActions()) {
// This check only works on actions as env vars don't persist between calls to the runner
const sentinelEnvVar = "CODEQL_UPLOAD_SARIF";
if (process.env[sentinelEnvVar]) {
@@ -243,12 +243,12 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
validateSarifFileSchema(file, logger);
}
let sarifPayload = combineSarifFiles(sarifFiles);
sarifPayload = fingerprints.addFingerprints(sarifPayload, checkoutPath, logger);
sarifPayload = await fingerprints.addFingerprints(sarifPayload, checkoutPath, logger);
sarifPayload = populateRunAutomationDetails(sarifPayload, category, analysisKey, environment);
const zippedSarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
const checkoutURI = file_url_1.default(checkoutPath);
const toolNames = util.getToolNames(sarifPayload);
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion, mode);
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion);
// Log some useful debug info about the info
const rawUploadSizeBytes = sarifPayload.length;
logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`);
@@ -257,7 +257,7 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
const numResultInSarif = countResultsInSarif(sarifPayload);
logger.debug(`Number of results in upload: ${numResultInSarif}`);
// Make the upload
await uploadPayload(payload, repositoryNwo, apiDetails, mode, logger);
await uploadPayload(payload, repositoryNwo, apiDetails, logger);
logger.endGroup();
return {
raw_upload_size_bytes: rawUploadSizeBytes,

File diff suppressed because one or more lines are too long

View File

@@ -18,6 +18,9 @@ const testing_utils_1 = require("./testing-utils");
const uploadLib = __importStar(require("./upload-lib"));
const util_1 = require("./util");
testing_utils_1.setupTests(ava_1.default);
ava_1.default.beforeEach(() => {
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
});
ava_1.default("validateSarifFileSchema - valid", (t) => {
const inputFile = `${__dirname}/../src/testdata/valid-sarif.sarif`;
t.notThrows(() => uploadLib.validateSarifFileSchema(inputFile, logging_1.getRunnerLogger(true)));
@@ -38,7 +41,7 @@ ava_1.default("validate correct payload used per version", async (t) => {
const allVersions = newVersions.concat(oldVersions);
process.env["GITHUB_EVENT_NAME"] = "push";
for (const version of allVersions) {
const payload = uploadLib.buildPayload("commit", "refs/heads/master", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "actions");
const payload = uploadLib.buildPayload("commit", "refs/heads/master", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
// Not triggered by a pull request
t.falsy(payload.base_ref);
t.falsy(payload.base_sha);
@@ -46,12 +49,12 @@ ava_1.default("validate correct payload used per version", async (t) => {
process.env["GITHUB_EVENT_NAME"] = "pull_request";
process.env["GITHUB_EVENT_PATH"] = `${__dirname}/../src/testdata/pull_request.json`;
for (const version of newVersions) {
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "actions");
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
t.deepEqual(payload.base_ref, "refs/heads/master");
t.deepEqual(payload.base_sha, "f95f852bd8fca8fcc58a9a2d6c842781e32a215e");
}
for (const version of oldVersions) {
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "actions");
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
// These older versions won't expect these values
t.falsy(payload.base_ref);
t.falsy(payload.base_sha);

View File

@@ -1 +1 @@
{"version":3,"file":"upload-lib.test.js","sourceRoot":"","sources":["../src/upload-lib.test.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"upload-lib.test.js","sourceRoot":"","sources":["../src/upload-lib.test.ts"],"names":[],"mappings":"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"}

View File

@@ -12,6 +12,8 @@ const actionsUtil = __importStar(require("./actions-util"));
const logging_1 = require("./logging");
const upload_lib = __importStar(require("./upload-lib"));
const util_1 = require("./util");
// eslint-disable-next-line import/no-commonjs
const pkg = require("../package.json");
async function sendSuccessStatusReport(startedAt, uploadStats) {
const statusReportBase = await actionsUtil.createStatusReportBase("upload-sarif", "success", startedAt);
const statusReport = {
@@ -21,6 +23,7 @@ async function sendSuccessStatusReport(startedAt, uploadStats) {
await actionsUtil.sendStatusReport(statusReport);
}
async function run() {
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
const startedAt = new Date();
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("upload-sarif", "starting", startedAt)))) {
return;
@@ -28,7 +31,7 @@ async function run() {
try {
const apiDetails = {
auth: actionsUtil.getRequiredInput("token"),
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
};
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
const uploadStats = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), gitHubVersion, apiDetails, logging_1.getActionsLogger());

View File

@@ -1 +1 @@
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,uCAA6C;AAC7C,yDAA2C;AAC3C,iCAA0C;AAM1C,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,WAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,cAAc,EACd,SAAS,EACT,SAAS,CACV,CAAC;IACF,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAG,WAAW;KACf,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,UAAU,EACV,SAAS,CACV,CACF,CAAC,EACF;QACA,OAAO;KACR;IAED,IAAI;QACF,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;YAC3C,GAAG,EAAE,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC;SAC1D,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,uBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACpD,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAC1C,aAAa,EACb,UAAU,EACV,0BAAgB,EAAE,CACnB,CAAC;QACF,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KACvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,WAAW,CAAC,gBAAgB,CAChC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;KACR;AACH,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,uCAA6C;AAC7C,yDAA2C;AAC3C,iCAKgB;AAEhB,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAMvC,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,WAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,cAAc,EACd,SAAS,EACT,SAAS,CACV,CAAC;IACF,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAG,WAAW;KACf,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,UAAU,EACV,SAAS,CACV,CACF,CAAC,EACF;QACA,OAAO;KACR;IAED,IAAI;QACF,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;YAC3C,GAAG,EAAE,0BAAmB,CAAC,mBAAmB,CAAC;SAC9C,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,uBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACpD,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAC1C,aAAa,EACb,UAAU,EACV,0BAAgB,EAAE,CACnB,CAAC;QACF,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KACvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,WAAW,CAAC,gBAAgB,CAChC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;KACR;AACH,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}

108
lib/util.js generated
View File

@@ -35,12 +35,6 @@ function getExtraOptionsEnvParam() {
}
}
exports.getExtraOptionsEnvParam = getExtraOptionsEnvParam;
function isLocalRun() {
return (!!process.env.CODEQL_LOCAL_RUN &&
process.env.CODEQL_LOCAL_RUN !== "false" &&
process.env.CODEQL_LOCAL_RUN !== "0");
}
exports.isLocalRun = isLocalRun;
/**
* Get the array of all the tool names contained in the given sarif contents.
*
@@ -229,12 +223,11 @@ async function getGitHubVersion(apiDetails) {
return { type: GitHubVariant.GHES, version };
}
exports.getGitHubVersion = getGitHubVersion;
function checkGitHubVersionInRange(version, mode, logger) {
function checkGitHubVersionInRange(version, logger, toolName) {
if (hasBeenWarnedAboutVersion || version.type !== GitHubVariant.GHES) {
return;
}
const disallowedAPIVersionReason = apiVersionInRange(version.version, apiCompatibility.minimumVersion, apiCompatibility.maximumVersion);
const toolName = mode === "actions" ? "Action" : "Runner";
if (disallowedAPIVersionReason === DisallowedAPIVersionReason.ACTION_TOO_OLD) {
logger.warning(`The CodeQL ${toolName} version you are using is too old to be compatible with GitHub Enterprise ${version.version}. If you experience issues, please upgrade to a more recent version of the CodeQL ${toolName}.`);
}
@@ -242,7 +235,7 @@ function checkGitHubVersionInRange(version, mode, logger) {
logger.warning(`GitHub Enterprise ${version.version} is too old to be compatible with this version of the CodeQL ${toolName}. If you experience issues, please upgrade to a more recent version of GitHub Enterprise or use an older version of the CodeQL ${toolName}.`);
}
hasBeenWarnedAboutVersion = true;
if (mode === "actions") {
if (isActions()) {
core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
}
}
@@ -330,4 +323,101 @@ function assertNever(value) {
throw new ExhaustivityCheckingError(value);
}
exports.assertNever = assertNever;
var Mode;
(function (Mode) {
Mode["actions"] = "Action";
Mode["runner"] = "Runner";
})(Mode = exports.Mode || (exports.Mode = {}));
/**
* Environment variables to be set by codeql-action and used by the
* CLI. These environment variables are relevant for both the runner
* and the action.
*/
var EnvVar;
(function (EnvVar) {
/**
* The mode of the codeql-action, either 'actions' or 'runner'.
*/
EnvVar["RUN_MODE"] = "CODEQL_ACTION_RUN_MODE";
/**
* Semver of the codeql-action as specified in package.json.
*/
EnvVar["VERSION"] = "CODEQL_ACTION_VERSION";
/**
* If set to a truthy value, then the codeql-action might combine SARIF
* output from several `interpret-results` runs for the same Language.
*/
EnvVar["FEATURE_SARIF_COMBINE"] = "CODEQL_ACTION_FEATURE_SARIF_COMBINE";
/**
* If set to the "true" string, then the codeql-action will upload SARIF,
* not the cli.
*/
EnvVar["FEATURE_WILL_UPLOAD"] = "CODEQL_ACTION_FEATURE_WILL_UPLOAD";
/**
* If set to the "true" string, then the codeql-action is using its
* own deprecated and non-standard way of scanning for multiple
* languages.
*/
EnvVar["FEATURE_MULTI_LANGUAGE"] = "CODEQL_ACTION_FEATURE_MULTI_LANGUAGE";
/**
* If set to the "true" string, then the codeql-action is using its
* own sandwiched workflow mechanism
*/
EnvVar["FEATURE_SANDWICH"] = "CODEQL_ACTION_FEATURE_SANDWICH";
})(EnvVar || (EnvVar = {}));
function initializeEnvironment(mode, version) {
const exportVar = (name, value) => {
if (mode === Mode.actions) {
core.exportVariable(name, value);
}
else {
process.env[name] = value;
}
};
exportVar(EnvVar.RUN_MODE, mode);
exportVar(EnvVar.VERSION, version);
exportVar(EnvVar.FEATURE_SARIF_COMBINE, "true");
exportVar(EnvVar.FEATURE_WILL_UPLOAD, "true");
exportVar(EnvVar.FEATURE_MULTI_LANGUAGE, "true");
exportVar(EnvVar.FEATURE_SANDWICH, "true");
}
exports.initializeEnvironment = initializeEnvironment;
function getMode() {
// Make sure we fail fast if the env var is missing. This should
// only happen if there is a bug in our code and we neglected
// to set the mode early in the process.
const mode = getRequiredEnvParam(EnvVar.RUN_MODE);
if (mode !== Mode.actions && mode !== Mode.runner) {
throw new Error(`Unknown mode: ${mode}.`);
}
return mode;
}
exports.getMode = getMode;
function isActions() {
return getMode() === Mode.actions;
}
exports.isActions = isActions;
/**
* Get an environment parameter, but throw an error if it is not set.
*/
function getRequiredEnvParam(paramName) {
const value = process.env[paramName];
if (value === undefined || value.length === 0) {
throw new Error(`${paramName} environment variable must be set`);
}
return value;
}
exports.getRequiredEnvParam = getRequiredEnvParam;
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
}
exports.HTTPError = HTTPError;
function isHTTPError(arg) {
var _a;
return ((_a = arg) === null || _a === void 0 ? void 0 : _a.status) !== undefined && Number.isInteger(arg.status);
}
exports.isHTTPError = isHTTPError;
//# sourceMappingURL=util.js.map

File diff suppressed because one or more lines are too long

12
lib/util.test.js generated
View File

@@ -70,18 +70,6 @@ ava_1.default("getThreadsFlag() should return the correct --threads flag", (t) =
ava_1.default("getThreadsFlag() throws if the threads input is not an integer", (t) => {
t.throws(() => util.getThreadsFlag("hello!", logging_1.getRunnerLogger(true)));
});
ava_1.default("isLocalRun() runs correctly", (t) => {
process.env.CODEQL_LOCAL_RUN = "";
t.assert(!util.isLocalRun());
process.env.CODEQL_LOCAL_RUN = "false";
t.assert(!util.isLocalRun());
process.env.CODEQL_LOCAL_RUN = "0";
t.assert(!util.isLocalRun());
process.env.CODEQL_LOCAL_RUN = "true";
t.assert(util.isLocalRun());
process.env.CODEQL_LOCAL_RUN = "hucairz";
t.assert(util.isLocalRun());
});
ava_1.default("getExtraOptionsEnvParam() succeeds on valid JSON with invalid options (for now)", (t) => {
const origExtraOptions = process.env.CODEQL_ACTION_EXTRA_OPTIONS;
const options = { foo: 42 };

File diff suppressed because one or more lines are too long

2183
node_modules/.package-lock.json generated vendored

File diff suppressed because it is too large Load Diff

9
node_modules/@actions/artifact/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

213
node_modules/@actions/artifact/README.md generated vendored Normal file
View File

@@ -0,0 +1,213 @@
# `@actions/artifact`
## Usage
You can use this package to interact with the actions artifacts.
- [Upload an Artifact](#Upload-an-Artifact)
- [Download a Single Artifact](#Download-a-Single-Artifact)
- [Download All Artifacts](#Download-all-Artifacts)
- [Additional Documentation](#Additional-Documentation)
- [Contributions](#Contributions)
Relative paths and absolute paths are both allowed. Relative paths are rooted against the current working directory.
## Upload an Artifact
Method Name: `uploadArtifact`
#### Inputs
- `name`
- The name of the artifact that is being uploaded
- Required
- `files`
- A list of file paths that describe what should be uploaded as part of the artifact
- If a path is provided that does not exist, an error will be thrown
- Can be absolute or relative. Internally everything is normalized and resolved
- Required
- `rootDirectory`
- A file path that denotes the root directory of the files being uploaded. This path is used to strip the paths provided in `files` to control how they are uploaded and structured
- If a file specified in `files` is not in the `rootDirectory`, an error will be thrown
- Required
- `options`
- Extra options that allow for the customization of the upload behavior
- Optional
#### Available Options
- `continueOnError`
- Indicates if the artifact upload should continue in the event a file fails to upload. If there is a error during upload, a partial artifact will always be created and available for download at the end. The `size` reported will be the amount of storage that the user or org will be charged for the partial artifact.
- If set to `false`, and an error is encountered, all other uploads will stop and any files that were queued will not be attempted to be uploaded. The partial artifact available will only include files up until the failure.
- If set to `true` and an error is encountered, the failed file will be skipped and ignored and all other queued files will be attempted to be uploaded. There will be an artifact available for download at the end with everything excluding the file that failed to upload
- Optional, defaults to `true` if not specified
- `retentionDays`
- Duration after which artifact will expire in days
- Minimum value: 1
- Maximum value: 90 unless changed by repository setting
- If this is set to a greater value than the retention settings allowed, the retention on artifacts will be reduced to match the max value allowed on the server, and the upload process will continue. An input of 0 assumes default retention value.
#### Example using Absolute File Paths
```js
const artifact = require('@actions/artifact');
const artifactClient = artifact.create()
const artifactName = 'my-artifact';
const files = [
'/home/user/files/plz-upload/file1.txt',
'/home/user/files/plz-upload/file2.txt',
'/home/user/files/plz-upload/dir/file3.txt'
]
const rootDirectory = '/home/user/files/plz-upload'
const options = {
continueOnError: true
}
const uploadResult = await artifactClient.uploadArtifact(artifactName, files, rootDirectory, options)
```
#### Example using Relative File Paths
```js
// Assuming the current working directory is /home/user/files/plz-upload
const artifact = require('@actions/artifact');
const artifactClient = artifact.create()
const artifactName = 'my-artifact';
const files = [
'file1.txt',
'file2.txt',
'dir/file3.txt'
]
const rootDirectory = '.' // Also possible to use __dirname
const options = {
continueOnError: false
}
const uploadResponse = await artifactClient.uploadArtifact(artifactName, files, rootDirectory, options)
```
#### Upload Result
The returned `UploadResponse` will contain the following information
- `artifactName`
- The name of the artifact that was uploaded
- `artifactItems`
- A list of all files that describe what is uploaded if there are no errors encountered. Usually this will be equal to the inputted `files` with the exception of empty directories (will not be uploaded)
- `size`
- Total size of the artifact that was uploaded in bytes
- `failedItems`
- A list of items that were not uploaded successfully (this will include queued items that were not uploaded if `continueOnError` is set to false). This is a subset of `artifactItems`
## Download a Single Artifact
Method Name: `downloadArtifact`
#### Inputs
- `name`
- The name of the artifact to download
- Required
- `path`
- Path that denotes where the artifact will be downloaded to
- Optional. Defaults to the GitHub workspace directory(`$GITHUB_WORKSPACE`) if not specified
- `options`
- Extra options that allow for the customization of the download behavior
- Optional
#### Available Options
- `createArtifactFolder`
- Specifies if a folder (the artifact name) is created for the artifact that is downloaded (contents downloaded into this folder),
- Optional. Defaults to false if not specified
#### Example
```js
const artifact = require('@actions/artifact');
const artifactClient = artifact.create()
const artifactName = 'my-artifact';
const path = 'some/directory'
const options = {
createArtifactFolder: false
}
const downloadResponse = await artifactClient.downloadArtifact(artifactName, path, options)
// Post download, the directory structure will look like this
/some
/directory
/file1.txt
/file2.txt
/dir
/file3.txt
// If createArtifactFolder is set to true, the directory structure will look like this
/some
/directory
/my-artifact
/file1.txt
/file2.txt
/dir
/file3.txt
```
#### Download Response
The returned `DownloadResponse` will contain the following information
- `artifactName`
- The name of the artifact that was downloaded
- `downloadPath`
- The full Path to where the artifact was downloaded
## Download All Artifacts
Method Name: `downloadAllArtifacts`
#### Inputs
- `path`
- Path that denotes where the artifact will be downloaded to
- Optional. Defaults to the GitHub workspace directory(`$GITHUB_WORKSPACE`) if not specified
```js
const artifact = require('@actions/artifact');
const artifactClient = artifact.create();
const downloadResponse = await artifactClient.downloadAllArtifacts();
// output result
for (response in downloadResponse) {
console.log(response.artifactName);
console.log(response.downloadPath);
}
```
Because there are multiple artifacts, an extra directory (denoted by the name of the artifact) will be created for each artifact in the path. With 2 artifacts(`my-artifact-1` and `my-artifact-2` for example) and the default path, the directory structure will be as follows:
```js
/GITHUB_WORKSPACE
/my-artifact-1
/ .. contents of `my-artifact-1`
/my-artifact-2
/ .. contents of `my-artifact-2`
```
#### Download Result
An array will be returned that describes the results for downloading all artifacts. The number of items in the array indicates the number of artifacts that were downloaded.
Each artifact will have the same `DownloadResponse` as if it was individually downloaded
- `artifactName`
- The name of the artifact that was downloaded
- `downloadPath`
- The full Path to where the artifact was downloaded
## Additional Documentation
Check out [additional-information](docs/additional-information.md) for extra documentation around usage, restrictions and behavior.
Check out [implementation-details](docs/implementation-details.md) for extra information about the implementation of this package.
## Contributions
See [contributor guidelines](https://github.com/actions/toolkit/blob/main/.github/CONTRIBUTING.md) for general guidelines and information about toolkit contributions.
For contributions related to this package, see [artifact contributions](CONTRIBUTIONS.md) for more information.

View File

@@ -0,0 +1,10 @@
import { UploadOptions } from './internal/upload-options';
import { UploadResponse } from './internal/upload-response';
import { DownloadOptions } from './internal/download-options';
import { DownloadResponse } from './internal/download-response';
import { ArtifactClient } from './internal/artifact-client';
export { ArtifactClient, UploadResponse, UploadOptions, DownloadResponse, DownloadOptions };
/**
* Constructs an ArtifactClient
*/
export declare function create(): ArtifactClient;

11
node_modules/@actions/artifact/lib/artifact-client.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const artifact_client_1 = require("./internal/artifact-client");
/**
* Constructs an ArtifactClient
*/
function create() {
return artifact_client_1.DefaultArtifactClient.create();
}
exports.create = create;
//# sourceMappingURL=artifact-client.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"artifact-client.js","sourceRoot":"","sources":["../src/artifact-client.ts"],"names":[],"mappings":";;AAIA,gEAAgF;AAUhF;;GAEG;AACH,SAAgB,MAAM;IACpB,OAAO,uCAAqB,CAAC,MAAM,EAAE,CAAA;AACvC,CAAC;AAFD,wBAEC"}

View File

@@ -0,0 +1,41 @@
import { UploadResponse } from './upload-response';
import { UploadOptions } from './upload-options';
import { DownloadOptions } from './download-options';
import { DownloadResponse } from './download-response';
export interface ArtifactClient {
/**
* Uploads an artifact
*
* @param name the name of the artifact, required
* @param files a list of absolute or relative paths that denote what files should be uploaded
* @param rootDirectory an absolute or relative file path that denotes the root parent directory of the files being uploaded
* @param options extra options for customizing the upload behavior
* @returns single UploadInfo object
*/
uploadArtifact(name: string, files: string[], rootDirectory: string, options?: UploadOptions): Promise<UploadResponse>;
/**
* Downloads a single artifact associated with a run
*
* @param name the name of the artifact being downloaded
* @param path optional path that denotes where the artifact will be downloaded to
* @param options extra options that allow for the customization of the download behavior
*/
downloadArtifact(name: string, path?: string, options?: DownloadOptions): Promise<DownloadResponse>;
/**
* Downloads all artifacts associated with a run. Because there are multiple artifacts being downloaded, a folder will be created for each one in the specified or default directory
* @param path optional path that denotes where the artifacts will be downloaded to
*/
downloadAllArtifacts(path?: string): Promise<DownloadResponse[]>;
}
export declare class DefaultArtifactClient implements ArtifactClient {
/**
* Constructs a DefaultArtifactClient
*/
static create(): DefaultArtifactClient;
/**
* Uploads an artifact
*/
uploadArtifact(name: string, files: string[], rootDirectory: string, options?: UploadOptions | undefined): Promise<UploadResponse>;
downloadArtifact(name: string, path?: string | undefined, options?: DownloadOptions | undefined): Promise<DownloadResponse>;
downloadAllArtifacts(path?: string | undefined): Promise<DownloadResponse[]>;
}

View File

@@ -0,0 +1,149 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const upload_specification_1 = require("./upload-specification");
const upload_http_client_1 = require("./upload-http-client");
const utils_1 = require("./utils");
const download_http_client_1 = require("./download-http-client");
const download_specification_1 = require("./download-specification");
const config_variables_1 = require("./config-variables");
const path_1 = require("path");
class DefaultArtifactClient {
/**
* Constructs a DefaultArtifactClient
*/
static create() {
return new DefaultArtifactClient();
}
/**
* Uploads an artifact
*/
uploadArtifact(name, files, rootDirectory, options) {
return __awaiter(this, void 0, void 0, function* () {
utils_1.checkArtifactName(name);
// Get specification for the files being uploaded
const uploadSpecification = upload_specification_1.getUploadSpecification(name, rootDirectory, files);
const uploadResponse = {
artifactName: name,
artifactItems: [],
size: 0,
failedItems: []
};
const uploadHttpClient = new upload_http_client_1.UploadHttpClient();
if (uploadSpecification.length === 0) {
core.warning(`No files found that can be uploaded`);
}
else {
// Create an entry for the artifact in the file container
const response = yield uploadHttpClient.createArtifactInFileContainer(name, options);
if (!response.fileContainerResourceUrl) {
core.debug(response.toString());
throw new Error('No URL provided by the Artifact Service to upload an artifact to');
}
core.debug(`Upload Resource URL: ${response.fileContainerResourceUrl}`);
// Upload each of the files that were found concurrently
const uploadResult = yield uploadHttpClient.uploadArtifactToFileContainer(response.fileContainerResourceUrl, uploadSpecification, options);
// Update the size of the artifact to indicate we are done uploading
// The uncompressed size is used for display when downloading a zip of the artifact from the UI
yield uploadHttpClient.patchArtifactSize(uploadResult.totalSize, name);
core.info(`Finished uploading artifact ${name}. Reported size is ${uploadResult.uploadSize} bytes. There were ${uploadResult.failedItems.length} items that failed to upload`);
uploadResponse.artifactItems = uploadSpecification.map(item => item.absoluteFilePath);
uploadResponse.size = uploadResult.uploadSize;
uploadResponse.failedItems = uploadResult.failedItems;
}
return uploadResponse;
});
}
downloadArtifact(name, path, options) {
return __awaiter(this, void 0, void 0, function* () {
const downloadHttpClient = new download_http_client_1.DownloadHttpClient();
const artifacts = yield downloadHttpClient.listArtifacts();
if (artifacts.count === 0) {
throw new Error(`Unable to find any artifacts for the associated workflow`);
}
const artifactToDownload = artifacts.value.find(artifact => {
return artifact.name === name;
});
if (!artifactToDownload) {
throw new Error(`Unable to find an artifact with the name: ${name}`);
}
const items = yield downloadHttpClient.getContainerItems(artifactToDownload.name, artifactToDownload.fileContainerResourceUrl);
if (!path) {
path = config_variables_1.getWorkSpaceDirectory();
}
path = path_1.normalize(path);
path = path_1.resolve(path);
// During upload, empty directories are rejected by the remote server so there should be no artifacts that consist of only empty directories
const downloadSpecification = download_specification_1.getDownloadSpecification(name, items.value, path, (options === null || options === void 0 ? void 0 : options.createArtifactFolder) || false);
if (downloadSpecification.filesToDownload.length === 0) {
core.info(`No downloadable files were found for the artifact: ${artifactToDownload.name}`);
}
else {
// Create all necessary directories recursively before starting any download
yield utils_1.createDirectoriesForArtifact(downloadSpecification.directoryStructure);
core.info('Directory structure has been setup for the artifact');
yield utils_1.createEmptyFilesForArtifact(downloadSpecification.emptyFilesToCreate);
yield downloadHttpClient.downloadSingleArtifact(downloadSpecification.filesToDownload);
}
return {
artifactName: name,
downloadPath: downloadSpecification.rootDownloadLocation
};
});
}
downloadAllArtifacts(path) {
return __awaiter(this, void 0, void 0, function* () {
const downloadHttpClient = new download_http_client_1.DownloadHttpClient();
const response = [];
const artifacts = yield downloadHttpClient.listArtifacts();
if (artifacts.count === 0) {
core.info('Unable to find any artifacts for the associated workflow');
return response;
}
if (!path) {
path = config_variables_1.getWorkSpaceDirectory();
}
path = path_1.normalize(path);
path = path_1.resolve(path);
let downloadedArtifacts = 0;
while (downloadedArtifacts < artifacts.count) {
const currentArtifactToDownload = artifacts.value[downloadedArtifacts];
downloadedArtifacts += 1;
// Get container entries for the specific artifact
const items = yield downloadHttpClient.getContainerItems(currentArtifactToDownload.name, currentArtifactToDownload.fileContainerResourceUrl);
const downloadSpecification = download_specification_1.getDownloadSpecification(currentArtifactToDownload.name, items.value, path, true);
if (downloadSpecification.filesToDownload.length === 0) {
core.info(`No downloadable files were found for any artifact ${currentArtifactToDownload.name}`);
}
else {
yield utils_1.createDirectoriesForArtifact(downloadSpecification.directoryStructure);
yield utils_1.createEmptyFilesForArtifact(downloadSpecification.emptyFilesToCreate);
yield downloadHttpClient.downloadSingleArtifact(downloadSpecification.filesToDownload);
}
response.push({
artifactName: currentArtifactToDownload.name,
downloadPath: downloadSpecification.rootDownloadLocation
});
}
return response;
});
}
}
exports.DefaultArtifactClient = DefaultArtifactClient;
//# sourceMappingURL=artifact-client.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"artifact-client.js","sourceRoot":"","sources":["../../src/internal/artifact-client.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,11 @@
export declare function getUploadFileConcurrency(): number;
export declare function getUploadChunkSize(): number;
export declare function getRetryLimit(): number;
export declare function getRetryMultiplier(): number;
export declare function getInitialRetryIntervalInMilliseconds(): number;
export declare function getDownloadFileConcurrency(): number;
export declare function getRuntimeToken(): string;
export declare function getRuntimeUrl(): string;
export declare function getWorkFlowRunId(): string;
export declare function getWorkSpaceDirectory(): string;
export declare function getRetentionDays(): string | undefined;

View File

@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// The number of concurrent uploads that happens at the same time
function getUploadFileConcurrency() {
return 2;
}
exports.getUploadFileConcurrency = getUploadFileConcurrency;
// When uploading large files that can't be uploaded with a single http call, this controls
// the chunk size that is used during upload
function getUploadChunkSize() {
return 8 * 1024 * 1024; // 8 MB Chunks
}
exports.getUploadChunkSize = getUploadChunkSize;
// The maximum number of retries that can be attempted before an upload or download fails
function getRetryLimit() {
return 5;
}
exports.getRetryLimit = getRetryLimit;
// With exponential backoff, the larger the retry count, the larger the wait time before another attempt
// The retry multiplier controls by how much the backOff time increases depending on the number of retries
function getRetryMultiplier() {
return 1.5;
}
exports.getRetryMultiplier = getRetryMultiplier;
// The initial wait time if an upload or download fails and a retry is being attempted for the first time
function getInitialRetryIntervalInMilliseconds() {
return 3000;
}
exports.getInitialRetryIntervalInMilliseconds = getInitialRetryIntervalInMilliseconds;
// The number of concurrent downloads that happens at the same time
function getDownloadFileConcurrency() {
return 2;
}
exports.getDownloadFileConcurrency = getDownloadFileConcurrency;
function getRuntimeToken() {
const token = process.env['ACTIONS_RUNTIME_TOKEN'];
if (!token) {
throw new Error('Unable to get ACTIONS_RUNTIME_TOKEN env variable');
}
return token;
}
exports.getRuntimeToken = getRuntimeToken;
function getRuntimeUrl() {
const runtimeUrl = process.env['ACTIONS_RUNTIME_URL'];
if (!runtimeUrl) {
throw new Error('Unable to get ACTIONS_RUNTIME_URL env variable');
}
return runtimeUrl;
}
exports.getRuntimeUrl = getRuntimeUrl;
function getWorkFlowRunId() {
const workFlowRunId = process.env['GITHUB_RUN_ID'];
if (!workFlowRunId) {
throw new Error('Unable to get GITHUB_RUN_ID env variable');
}
return workFlowRunId;
}
exports.getWorkFlowRunId = getWorkFlowRunId;
function getWorkSpaceDirectory() {
const workspaceDirectory = process.env['GITHUB_WORKSPACE'];
if (!workspaceDirectory) {
throw new Error('Unable to get GITHUB_WORKSPACE env variable');
}
return workspaceDirectory;
}
exports.getWorkSpaceDirectory = getWorkSpaceDirectory;
function getRetentionDays() {
return process.env['GITHUB_RETENTION_DAYS'];
}
exports.getRetentionDays = getRetentionDays;
//# sourceMappingURL=config-variables.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"config-variables.js","sourceRoot":"","sources":["../../src/internal/config-variables.ts"],"names":[],"mappings":";;AAAA,iEAAiE;AACjE,SAAgB,wBAAwB;IACtC,OAAO,CAAC,CAAA;AACV,CAAC;AAFD,4DAEC;AAED,2FAA2F;AAC3F,4CAA4C;AAC5C,SAAgB,kBAAkB;IAChC,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA,CAAC,cAAc;AACvC,CAAC;AAFD,gDAEC;AAED,yFAAyF;AACzF,SAAgB,aAAa;IAC3B,OAAO,CAAC,CAAA;AACV,CAAC;AAFD,sCAEC;AAED,wGAAwG;AACxG,0GAA0G;AAC1G,SAAgB,kBAAkB;IAChC,OAAO,GAAG,CAAA;AACZ,CAAC;AAFD,gDAEC;AAED,yGAAyG;AACzG,SAAgB,qCAAqC;IACnD,OAAO,IAAI,CAAA;AACb,CAAC;AAFD,sFAEC;AAED,mEAAmE;AACnE,SAAgB,0BAA0B;IACxC,OAAO,CAAC,CAAA;AACV,CAAC;AAFD,gEAEC;AAED,SAAgB,eAAe;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IAClD,IAAI,CAAC,KAAK,EAAE;QACV,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;KACpE;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAND,0CAMC;AAED,SAAgB,aAAa;IAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;IACrD,IAAI,CAAC,UAAU,EAAE;QACf,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;KAClE;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAND,sCAMC;AAED,SAAgB,gBAAgB;IAC9B,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAClD,IAAI,CAAC,aAAa,EAAE;QAClB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;KAC5D;IACD,OAAO,aAAa,CAAA;AACtB,CAAC;AAND,4CAMC;AAED,SAAgB,qBAAqB;IACnC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC1D,IAAI,CAAC,kBAAkB,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;KAC/D;IACD,OAAO,kBAAkB,CAAA;AAC3B,CAAC;AAND,sDAMC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;AAC7C,CAAC;AAFD,4CAEC"}

View File

@@ -0,0 +1,57 @@
export interface ArtifactResponse {
containerId: string;
size: number;
signedContent: string;
fileContainerResourceUrl: string;
type: string;
name: string;
url: string;
}
export interface CreateArtifactParameters {
Type: string;
Name: string;
RetentionDays?: number;
}
export interface PatchArtifactSize {
Size: number;
}
export interface PatchArtifactSizeSuccessResponse {
containerId: number;
size: number;
signedContent: string;
type: string;
name: string;
url: string;
uploadUrl: string;
}
export interface UploadResults {
uploadSize: number;
totalSize: number;
failedItems: string[];
}
export interface ListArtifactsResponse {
count: number;
value: ArtifactResponse[];
}
export interface QueryArtifactResponse {
count: number;
value: ContainerEntry[];
}
export interface ContainerEntry {
containerId: number;
scopeIdentifier: string;
path: string;
itemType: string;
status: string;
fileLength?: number;
fileEncoding?: number;
fileType?: number;
dateCreated: string;
dateLastModified: string;
createdBy: string;
lastModifiedBy: string;
itemLocation: string;
contentLocation: string;
fileId?: number;
contentId: string;
}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=contracts.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/internal/contracts.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,39 @@
/// <reference types="node" />
import * as fs from 'fs';
import { ListArtifactsResponse, QueryArtifactResponse } from './contracts';
import { IHttpClientResponse } from '@actions/http-client/interfaces';
import { DownloadItem } from './download-specification';
export declare class DownloadHttpClient {
private downloadHttpManager;
private statusReporter;
constructor();
/**
* Gets a list of all artifacts that are in a specific container
*/
listArtifacts(): Promise<ListArtifactsResponse>;
/**
* Fetches a set of container items that describe the contents of an artifact
* @param artifactName the name of the artifact
* @param containerUrl the artifact container URL for the run
*/
getContainerItems(artifactName: string, containerUrl: string): Promise<QueryArtifactResponse>;
/**
* Concurrently downloads all the files that are part of an artifact
* @param downloadItems information about what items to download and where to save them
*/
downloadSingleArtifact(downloadItems: DownloadItem[]): Promise<void>;
/**
* Downloads an individual file
* @param httpClientIndex the index of the http client that is used to make all of the calls
* @param artifactLocation origin location where a file will be downloaded from
* @param downloadPath destination location for the file being downloaded
*/
private downloadIndividualFile;
/**
* Pipes the response from downloading an individual file to the appropriate destination stream while decoding gzip content if necessary
* @param response the http response received when downloading a file
* @param destinationStream the stream where the file should be written to
* @param isGzip a boolean denoting if the content is compressed using gzip and if we need to decode it
*/
pipeResponseToFile(response: IHttpClientResponse, destinationStream: fs.WriteStream, isGzip: boolean): Promise<void>;
}

View File

@@ -0,0 +1,275 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const core = __importStar(require("@actions/core"));
const zlib = __importStar(require("zlib"));
const utils_1 = require("./utils");
const url_1 = require("url");
const status_reporter_1 = require("./status-reporter");
const perf_hooks_1 = require("perf_hooks");
const http_manager_1 = require("./http-manager");
const config_variables_1 = require("./config-variables");
const requestUtils_1 = require("./requestUtils");
class DownloadHttpClient {
constructor() {
this.downloadHttpManager = new http_manager_1.HttpManager(config_variables_1.getDownloadFileConcurrency(), '@actions/artifact-download');
// downloads are usually significantly faster than uploads so display status information every second
this.statusReporter = new status_reporter_1.StatusReporter(1000);
}
/**
* Gets a list of all artifacts that are in a specific container
*/
listArtifacts() {
return __awaiter(this, void 0, void 0, function* () {
const artifactUrl = utils_1.getArtifactUrl();
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.downloadHttpManager.getClient(0);
const headers = utils_1.getDownloadHeaders('application/json');
const response = yield requestUtils_1.retryHttpClientRequest('List Artifacts', () => __awaiter(this, void 0, void 0, function* () { return client.get(artifactUrl, headers); }));
const body = yield response.readBody();
return JSON.parse(body);
});
}
/**
* Fetches a set of container items that describe the contents of an artifact
* @param artifactName the name of the artifact
* @param containerUrl the artifact container URL for the run
*/
getContainerItems(artifactName, containerUrl) {
return __awaiter(this, void 0, void 0, function* () {
// the itemPath search parameter controls which containers will be returned
const resourceUrl = new url_1.URL(containerUrl);
resourceUrl.searchParams.append('itemPath', artifactName);
// use the first client from the httpManager, `keep-alive` is not used so the connection will close immediately
const client = this.downloadHttpManager.getClient(0);
const headers = utils_1.getDownloadHeaders('application/json');
const response = yield requestUtils_1.retryHttpClientRequest('Get Container Items', () => __awaiter(this, void 0, void 0, function* () { return client.get(resourceUrl.toString(), headers); }));
const body = yield response.readBody();
return JSON.parse(body);
});
}
/**
* Concurrently downloads all the files that are part of an artifact
* @param downloadItems information about what items to download and where to save them
*/
downloadSingleArtifact(downloadItems) {
return __awaiter(this, void 0, void 0, function* () {
const DOWNLOAD_CONCURRENCY = config_variables_1.getDownloadFileConcurrency();
// limit the number of files downloaded at a single time
core.debug(`Download file concurrency is set to ${DOWNLOAD_CONCURRENCY}`);
const parallelDownloads = [...new Array(DOWNLOAD_CONCURRENCY).keys()];
let currentFile = 0;
let downloadedFiles = 0;
core.info(`Total number of files that will be downloaded: ${downloadItems.length}`);
this.statusReporter.setTotalNumberOfFilesToProcess(downloadItems.length);
this.statusReporter.start();
yield Promise.all(parallelDownloads.map((index) => __awaiter(this, void 0, void 0, function* () {
while (currentFile < downloadItems.length) {
const currentFileToDownload = downloadItems[currentFile];
currentFile += 1;
const startTime = perf_hooks_1.performance.now();
yield this.downloadIndividualFile(index, currentFileToDownload.sourceLocation, currentFileToDownload.targetPath);
if (core.isDebug()) {
core.debug(`File: ${++downloadedFiles}/${downloadItems.length}. ${currentFileToDownload.targetPath} took ${(perf_hooks_1.performance.now() - startTime).toFixed(3)} milliseconds to finish downloading`);
}
this.statusReporter.incrementProcessedCount();
}
})))
.catch(error => {
throw new Error(`Unable to download the artifact: ${error}`);
})
.finally(() => {
this.statusReporter.stop();
// safety dispose all connections
this.downloadHttpManager.disposeAndReplaceAllClients();
});
});
}
/**
* Downloads an individual file
* @param httpClientIndex the index of the http client that is used to make all of the calls
* @param artifactLocation origin location where a file will be downloaded from
* @param downloadPath destination location for the file being downloaded
*/
downloadIndividualFile(httpClientIndex, artifactLocation, downloadPath) {
return __awaiter(this, void 0, void 0, function* () {
let retryCount = 0;
const retryLimit = config_variables_1.getRetryLimit();
let destinationStream = fs.createWriteStream(downloadPath);
const headers = utils_1.getDownloadHeaders('application/json', true, true);
// a single GET request is used to download a file
const makeDownloadRequest = () => __awaiter(this, void 0, void 0, function* () {
const client = this.downloadHttpManager.getClient(httpClientIndex);
return yield client.get(artifactLocation, headers);
});
// check the response headers to determine if the file was compressed using gzip
const isGzip = (incomingHeaders) => {
return ('content-encoding' in incomingHeaders &&
incomingHeaders['content-encoding'] === 'gzip');
};
// Increments the current retry count and then checks if the retry limit has been reached
// If there have been too many retries, fail so the download stops. If there is a retryAfterValue value provided,
// it will be used
const backOff = (retryAfterValue) => __awaiter(this, void 0, void 0, function* () {
retryCount++;
if (retryCount > retryLimit) {
return Promise.reject(new Error(`Retry limit has been reached. Unable to download ${artifactLocation}`));
}
else {
this.downloadHttpManager.disposeAndReplaceClient(httpClientIndex);
if (retryAfterValue) {
// Back off by waiting the specified time denoted by the retry-after header
core.info(`Backoff due to too many requests, retry #${retryCount}. Waiting for ${retryAfterValue} milliseconds before continuing the download`);
yield utils_1.sleep(retryAfterValue);
}
else {
// Back off using an exponential value that depends on the retry count
const backoffTime = utils_1.getExponentialRetryTimeInMilliseconds(retryCount);
core.info(`Exponential backoff for retry #${retryCount}. Waiting for ${backoffTime} milliseconds before continuing the download`);
yield utils_1.sleep(backoffTime);
}
core.info(`Finished backoff for retry #${retryCount}, continuing with download`);
}
});
const isAllBytesReceived = (expected, received) => {
// be lenient, if any input is missing, assume success, i.e. not truncated
if (!expected ||
!received ||
process.env['ACTIONS_ARTIFACT_SKIP_DOWNLOAD_VALIDATION']) {
core.info('Skipping download validation.');
return true;
}
return parseInt(expected) === received;
};
const resetDestinationStream = (fileDownloadPath) => __awaiter(this, void 0, void 0, function* () {
destinationStream.close();
yield utils_1.rmFile(fileDownloadPath);
destinationStream = fs.createWriteStream(fileDownloadPath);
});
// keep trying to download a file until a retry limit has been reached
while (retryCount <= retryLimit) {
let response;
try {
response = yield makeDownloadRequest();
if (core.isDebug()) {
utils_1.displayHttpDiagnostics(response);
}
}
catch (error) {
// if an error is caught, it is usually indicative of a timeout so retry the download
core.info('An error occurred while attempting to download a file');
// eslint-disable-next-line no-console
console.log(error);
// increment the retryCount and use exponential backoff to wait before making the next request
yield backOff();
continue;
}
let forceRetry = false;
if (utils_1.isSuccessStatusCode(response.message.statusCode)) {
// The body contains the contents of the file however calling response.readBody() causes all the content to be converted to a string
// which can cause some gzip encoded data to be lost
// Instead of using response.readBody(), response.message is a readableStream that can be directly used to get the raw body contents
try {
const isGzipped = isGzip(response.message.headers);
yield this.pipeResponseToFile(response, destinationStream, isGzipped);
if (isGzipped ||
isAllBytesReceived(response.message.headers['content-length'], yield utils_1.getFileSize(downloadPath))) {
return;
}
else {
forceRetry = true;
}
}
catch (error) {
// retry on error, most likely streams were corrupted
forceRetry = true;
}
}
if (forceRetry || utils_1.isRetryableStatusCode(response.message.statusCode)) {
core.info(`A ${response.message.statusCode} response code has been received while attempting to download an artifact`);
resetDestinationStream(downloadPath);
// if a throttled status code is received, try to get the retryAfter header value, else differ to standard exponential backoff
utils_1.isThrottledStatusCode(response.message.statusCode)
? yield backOff(utils_1.tryGetRetryAfterValueTimeInMilliseconds(response.message.headers))
: yield backOff();
}
else {
// Some unexpected response code, fail immediately and stop the download
utils_1.displayHttpDiagnostics(response);
return Promise.reject(new Error(`Unexpected http ${response.message.statusCode} during download for ${artifactLocation}`));
}
}
});
}
/**
* Pipes the response from downloading an individual file to the appropriate destination stream while decoding gzip content if necessary
* @param response the http response received when downloading a file
* @param destinationStream the stream where the file should be written to
* @param isGzip a boolean denoting if the content is compressed using gzip and if we need to decode it
*/
pipeResponseToFile(response, destinationStream, isGzip) {
return __awaiter(this, void 0, void 0, function* () {
yield new Promise((resolve, reject) => {
if (isGzip) {
const gunzip = zlib.createGunzip();
response.message
.on('error', error => {
core.error(`An error occurred while attempting to read the response stream`);
gunzip.close();
destinationStream.close();
reject(error);
})
.pipe(gunzip)
.on('error', error => {
core.error(`An error occurred while attempting to decompress the response stream`);
destinationStream.close();
reject(error);
})
.pipe(destinationStream)
.on('close', () => {
resolve();
})
.on('error', error => {
core.error(`An error occurred while writing a downloaded file to ${destinationStream.path}`);
reject(error);
});
}
else {
response.message
.on('error', error => {
core.error(`An error occurred while attempting to read the response stream`);
destinationStream.close();
reject(error);
})
.pipe(destinationStream)
.on('close', () => {
resolve();
})
.on('error', error => {
core.error(`An error occurred while writing a downloaded file to ${destinationStream.path}`);
reject(error);
});
}
});
return;
});
}
}
exports.DownloadHttpClient = DownloadHttpClient;
//# sourceMappingURL=download-http-client.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
export interface DownloadOptions {
/**
* Specifies if a folder is created for the artifact that is downloaded (contents downloaded into this folder),
* defaults to false if not specified
* */
createArtifactFolder?: boolean;
}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=download-options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"download-options.js","sourceRoot":"","sources":["../../src/internal/download-options.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,10 @@
export interface DownloadResponse {
/**
* The name of the artifact that was downloaded
*/
artifactName: string;
/**
* The full Path to where the artifact was downloaded
*/
downloadPath: string;
}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=download-response.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"download-response.js","sourceRoot":"","sources":["../../src/internal/download-response.ts"],"names":[],"mappings":""}

Some files were not shown because too many files have changed in this diff Show More