Compare commits

..

19 Commits

Author SHA1 Message Date
Marco Gario
11e79a34aa Fix test for toolcache 2020-09-21 10:47:01 +02:00
Marco Gario
8547a7593c Disable dependency in CI 2020-09-21 09:30:30 +02:00
Marco Gario
f8e92620cb Merge remote-tracking branch 'origin/main' into platform_lang_pkg 2020-09-21 09:12:18 +02:00
Marco Gario
1157017557 Assume small bundles are available in the official repo 2020-09-17 17:47:01 +02:00
Marco Gario
c25320cfef Improve integration test 2020-09-17 14:27:56 +02:00
Marco Gario
7f2fa9ca20 Merge branch 'main' into platform_lang_pkg 2020-09-17 14:02:08 +02:00
Marco Gario
b9f08d924a Fix early termination 2020-09-17 13:58:16 +02:00
Marco Gario
4d836f4b5a fix linter 2020-09-15 15:50:23 +02:00
Marco Gario
b9e8fa6371 Merge remote-tracking branch 'origin/main' into platform_lang_pkg 2020-09-15 15:30:34 +02:00
Marco Gario
0ca7a34758 CI: Add test for small-bundles 2020-09-11 12:34:02 +02:00
Marco Gario
d093fc0304 Remove old workflow 2020-09-11 12:03:47 +02:00
Marco Gario
7b29d2e0a5 Move language functions in dedicated package 2020-09-11 12:02:17 +02:00
Marco Gario
588a28d3b5 Merge remote-tracking branch 'origin/main' into platform_lang_pkg 2020-09-11 11:45:31 +02:00
Marco Gario
57b0b7fd1d Add logic to download codeql platform-language pkg
* Add `bundleName` argument to `getCodeQLBundleDownloadURL`
* Add `languages` argument to `setupCodeQL`.

The logic now tries to find the platform-language pkg before defaulting
to the full bundle. We keep the toolcache clean by adding the pl version
to the tool version.
2020-09-09 13:53:11 +02:00
Marco Gario
d3d7dd4600 # This is a combination of 4 commits.
# This is the 1st commit message:

Add logic to download codeql platform-language pkg

* Add `bundleName` argument to `getCodeQLBundleDownloadURL`
* Add `languages` argument to `setupCodeQL`.

The logic now tries to find the platform-language pkg before defaulting
to the full bundle. We keep the toolcache clean by adding the pl version
to the tool version.

# The commit message #2 will be skipped:

# add test

# The commit message #3 will be skipped:

# cleanup

# The commit message #4 will be skipped:

# linter
2020-09-09 13:52:43 +02:00
Marco Gario
3f5bb98d7e # This is a combination of 4 commits.
# This is the 1st commit message:

Add logic to download codeql platform-language pkg

* Add `bundleName` argument to `getCodeQLBundleDownloadURL`
* Add `languages` argument to `setupCodeQL`.

The logic now tries to find the platform-language pkg before defaulting
to the full bundle. We keep the toolcache clean by adding the pl version
to the tool version.

# The commit message #2 will be skipped:

# Add simple fallback logic for download

# The commit message #3 will be skipped:

# wip linter

# The commit message #4 will be skipped:

# linter
2020-09-09 13:52:06 +02:00
Marco Gario
7951f91d00 Add logic to download codeql platform-language pkg
* Add `bundleName` argument to `getCodeQLBundleDownloadURL`
* Add `languages` argument to `setupCodeQL`.

The logic now tries to find the platform-language pkg before defaulting
to the full bundle. We keep the toolcache clean by adding the pl version
to the tool version.
2020-09-09 13:50:48 +02:00
Marco Gario
408e376177 Add test for bundle with platform and language 2020-09-09 13:50:27 +02:00
Marco Gario
e4c39c9b06 Add CI for testing small bundles 2020-09-09 13:50:27 +02:00
594 changed files with 152531 additions and 77387 deletions

View File

@@ -46,6 +46,7 @@
"@typescript-eslint/restrict-template-expressions": "off",
"eslint-comments/no-use": "off",
"func-style": "off",
"github/array-foreach": "off",
"github/no-then": "off",
"import/no-extraneous-dependencies": "off",
"no-shadow": "off",

View File

@@ -127,6 +127,48 @@ jobs:
env:
TEST_MODE: true
single-language-bundles:
# These are 21 jobs, run them only if the earlier multi-language job suceeded
# needs: multi-language-repo_test-autodetect-languages
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
language: ["none", "cpp", "csharp", "go", "java", "javascript", "python"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Move codeql-action
shell: bash
run: |
mkdir ../action
mv * .github ../action/
mv ../action/tests/multi-language-repo/{*,.github} .
# The next 2 steps are mutually exclusive.
# In one case, we setup codeql for a single language.
# In the other, we setup codeql for a platform
- name: Test language-specific bundle
uses: ./../action/init
if: matrix.language != 'none'
with:
languages: ${{ matrix.language }}
- name: Test platform-secific bundle
uses: ./../action/init
if: matrix.language == 'none'
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
env:
TEST_MODE: true
- name: Check ToolCache (language-specific bundle)
if: matrix.language != 'none'
shell: bash
run: test -n "$(find -maxdepth 1 -name "codeql-bundle-0.0.0-*.${OS}-${{matrix.language}}" -print -quit)"
test-proxy:
runs-on: ubuntu-latest
container:

View File

@@ -1,64 +0,0 @@
name: Test Python Package Installation
on:
push:
pull_request:
jobs:
test-setup-python-scripts:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest,windows-latest,macos-latest]
include:
- test_dir: python-setup/tests/pipenv/requests-2
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 2
- test_dir: python-setup/tests/pipenv/requests-3
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 3
- test_dir: python-setup/tests/poetry/requests-2
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 2
- test_dir: python-setup/tests/poetry/requests-3
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 3
- test_dir: python-setup/tests/requirements/requests-2
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 2
- test_dir: python-setup/tests/requirements/requests-3
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 3
- test_dir: python-setup/tests/setup_py/requests-2
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 2
- test_dir: python-setup/tests/setup_py/requests-3
test_script: $GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh 3
# This one shouldn't fail, but also won't install packages
- test_dir: python-setup/tests/requirements/non-standard-location
test_script: test -z $LGTM_INDEX_IMPORT_PATH
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: python
- name: Test Auto Package Installation
run: |
set -x
$GITHUB_WORKSPACE/python-setup/install_tools.sh
echo -e '\n\n\n\n\n' && sleep 0.5
cd $GITHUB_WORKSPACE/${{ matrix.test_dir }}
$GITHUB_WORKSPACE/python-setup/auto_install_packages.py /opt/hostedtoolcache/CodeQL/0.0.0-20200826/x64/codeql/
/bin/true
- name: Setup for extractor
run: |
echo $CODEQL_PYTHON
# only run if $CODEQL_PYTHON is set
test ! -z $CODEQL_PYTHON && $GITHUB_WORKSPACE/python-setup/tests/from_python_exe.py $CODEQL_PYTHON || /bin/true
- name: Verify packages installed
run: |
${{ matrix.test_script }}

View File

@@ -1,73 +0,0 @@
#
# Split the CodeQL Bundle into platform bundles
#
# Instructions:
# 1. Upload the new codeql-bundle (codeql-bundle.tar.gz) as an asset of the
# release (codeql-bundle-20200826)
# 2. Take note of the CLI Release used by the bundle (e.g., v2.2.5)
# 3. Manually launch this workflow file (via the Actions UI) specifying
# - The CLI Release (e.g., v2.2.5)
# - The release tag (e.g., codeql-bundle-20200826)
# 4. If everything succeeds you should see 3 new assets.
#
name: Split Bundle
on:
workflow_dispatch:
inputs:
cli-release:
description: 'CodeQL CLI Release (e.g., "v2.2.5")'
required: true
bundle-tag:
description: 'Tag of the bundle release (e.g., "codeql-bundle-20200826")'
required: true
jobs:
build:
runs-on: ubuntu-latest
env:
CLI_RELEASE: "${{ github.event.inputs.cli-release }}"
RELEASE_TAG: "${{ github.event.inputs.bundle-tag }}"
strategy:
fail-fast: false
matrix:
platform: ["linux64", "osx64", "win64"]
steps:
- name: Resolve Upload URL for the release
id: save_url
run: |
UPLOAD_URL=$(curl -sS \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${RELEASE_TAG}" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" | jq .upload_url | sed s/\"//g)
echo ${UPLOAD_URL}
echo "::set-output name=upload_url::${UPLOAD_URL}"
- name: Download CodeQL CLI and Bundle
run: |
wget --no-verbose "https://github.com/${GITHUB_REPOSITORY}/releases/download/${RELEASE_TAG}/codeql-bundle.tar.gz"
wget --no-verbose "https://github.com/github/codeql-cli-binaries/releases/download/${CLI_RELEASE}/codeql-${{matrix.platform}}.zip"
- name: Create Platform Package
# Replace the codeql-binaries with the platform specific ones
run: |
gunzip codeql-bundle.tar.gz
tar -f codeql-bundle.tar --delete codeql
unzip -q codeql-${{matrix.platform}}.zip
tar -f codeql-bundle.tar --append codeql
gzip codeql-bundle.tar
mv codeql-bundle.tar.gz codeql-bundle-${{matrix.platform}}.tar.gz
du -sh codeql-bundle-${{matrix.platform}}.tar.gz
- name: Upload Platform Package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.save_url.outputs.upload_url }}
asset_path: ./codeql-bundle-${{matrix.platform}}.tar.gz
asset_name: codeql-bundle-${{matrix.platform}}.tar.gz
asset_content_type: application/tar+gzip

View File

@@ -19,10 +19,6 @@ 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
setup-python-dependencies:
description: Try to auto-install your python dependencies
required: true
default: 'true'
runs:
using: 'node12'
main: '../lib/init-action.js'

29
lib/analyze.js generated
View File

@@ -7,7 +7,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const analysisPaths = __importStar(require("./analysis-paths"));
@@ -16,31 +15,6 @@ const languages_1 = require("./languages");
const sharedEnv = __importStar(require("./shared-environment"));
const upload_lib = __importStar(require("./upload-lib"));
const util = __importStar(require("./util"));
async function setupPythonExtractor(logger) {
const codeqlPython = process.env["CODEQL_PYTHON"];
if (codeqlPython === undefined || codeqlPython.length === 0) {
// If CODEQL_PYTHON is not set, no dependencies were installed, so we don't need to do anything
return;
}
let output = "";
const options = {
listeners: {
stdout: (data) => {
output += data.toString();
},
},
};
await new toolrunnner.ToolRunner(codeqlPython, [
"-c",
"import os; import pip; print(os.path.dirname(os.path.dirname(pip.__file__)))",
], options).exec();
logger.info(`Setting LGTM_INDEX_IMPORT_PATH=${output}`);
process.env["LGTM_INDEX_IMPORT_PATH"] = output;
output = "";
await new toolrunnner.ToolRunner(codeqlPython, ["-c", "import sys; print(sys.version_info[0])"], options).exec();
logger.info(`Setting LGTM_PYTHON_SETUP_VERSION=${output}`);
process.env["LGTM_PYTHON_SETUP_VERSION"] = output;
}
async function createdDBForScannedLanguages(config, logger) {
// Insert the LGTM_INDEX_X env vars at this point so they are set when
// we extract any scanned languages.
@@ -49,9 +23,6 @@ async function createdDBForScannedLanguages(config, logger) {
for (const language of config.languages) {
if (languages_1.isScannedLanguage(language)) {
logger.startGroup(`Extracting ${language}`);
if (language === languages_1.Language.python) {
await setupPythonExtractor(logger);
}
await codeql.extractScannedLanguage(util.getCodeQLDatabasePath(config.tempDir, language), language);
logger.endGroup();
}

View File

@@ -1 +1 @@
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":";;;;;;;;;AAAA,0EAA4D;AAC5D,uCAAyB;AACzB,2CAA6B;AAE7B,gEAAkD;AAClD,qCAAqC;AAErC,2CAA0D;AAG1D,gEAAkD;AAClD,yDAA2C;AAC3C,6CAA+B;AAmC/B,KAAK,UAAU,oBAAoB,CAAC,MAAc;IAChD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;QAC3D,+FAA+F;QAC/F,OAAO;KACR;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG;QACd,SAAS,EAAE;YACT,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5B,CAAC;SACF;KACF,CAAC;IAEF,MAAM,IAAI,WAAW,CAAC,UAAU,CAC9B,YAAY,EACZ;QACE,IAAI;QACJ,8EAA8E;KAC/E,EACD,OAAO,CACR,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,CAAC,IAAI,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,GAAG,MAAM,CAAC;IAE/C,MAAM,GAAG,EAAE,CAAC;IACZ,MAAM,IAAI,WAAW,CAAC,UAAU,CAC9B,YAAY,EACZ,CAAC,IAAI,EAAE,wCAAwC,CAAC,EAChD,OAAO,CACR,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,CAAC,IAAI,CAAC,qCAAqC,MAAM,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,GAAG,MAAM,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,4BAA4B,CACzC,MAA0B,EAC1B,MAAc;IAEd,sEAAsE;IACtE,oCAAoC;IACpC,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,IAAI,6BAAiB,CAAC,QAAQ,CAAC,EAAE;YAC/B,MAAM,CAAC,UAAU,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;YAE5C,IAAI,QAAQ,KAAK,oBAAQ,CAAC,MAAM,EAAE;gBAChC,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;aACpC;YAED,MAAM,MAAM,CAAC,sBAAsB,CACjC,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,EACpD,QAAQ,CACT,CAAC;YACF,MAAM,CAAC,QAAQ,EAAE,CAAC;SACnB;KACF;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,MAA0B,EAC1B,MAAc;IAEd,MAAM,4BAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,MAAM,CAAC,UAAU,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,CAAC,gBAAgB,CAC3B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CACrD,CAAC;QACF,MAAM,CAAC,QAAQ,EAAE,CAAC;KACnB;AACH,CAAC;AAED,2DAA2D;AACpD,KAAK,UAAU,UAAU,CAC9B,WAAmB,EACnB,UAAkB,EAClB,eAAuB,EACvB,WAAmB,EACnB,MAA0B,EAC1B,MAAc;IAEd,MAAM,YAAY,GAAwB,EAAE,CAAC;IAE7C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,MAAM,CAAC,UAAU,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;QAE3C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/D,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,gDAAgD,CAC9E,CAAC;SACH;QAED,IAAI;YACF,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;gBACxC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC5B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;oBAEvC,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAC7C,MAAM,CAAC,OAAO,EACd,QAAQ,CACT,CAAC;oBACF,uEAAuE;oBACvE,2EAA2E;oBAC3E,MAAM,cAAc,GAAG,GAAG,YAAY,YAAY,IAAI,MAAM,CAAC;oBAC7D,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;yBACrC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;yBACnC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACd,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;oBACrD,MAAM,CAAC,KAAK,CACV,wBAAwB,QAAQ,QAAQ,kBAAkB,EAAE,CAC7D,CAAC;oBAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,QAAQ,IAAI,IAAI,QAAQ,CAAC,CAAC;oBAEtE,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC3C,MAAM,MAAM,CAAC,eAAe,CAC1B,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,eAAe,EACf,WAAW,CACZ,CAAC;oBAEF,MAAM,CAAC,KAAK,CACV,8BAA8B,QAAQ,gBAAgB,SAAS,GAAG,CACnE,CAAC;oBACF,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAElB,yBAAyB;oBACzB,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;oBACrC,YAAY,CAAC,WAAW,IAAI,YAAY,QAAQ,cAAc,CAAC;wBAC7D,OAAO,GAAG,SAAS,CAAC;iBACvB;aACF;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,YAAY,CAAC,wBAAwB,GAAG,QAAQ,CAAC;YACjD,OAAO,YAAY,CAAC;SACrB;KACF;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAxED,gCAwEC;AAEM,KAAK,UAAU,UAAU,CAC9B,aAA4B,EAC5B,SAAiB,EACjB,GAAW,EACX,WAA+B,EAC/B,YAAgC,EAChC,aAAiC,EACjC,YAAoB,EACpB,WAA+B,EAC/B,UAAkB,EAClB,SAAiB,EACjB,QAAiB,EACjB,IAAe,EACf,SAAiB,EACjB,UAAkB,EAClB,eAAuB,EACvB,WAAmB,EACnB,MAA0B,EAC1B,MAAc;IAEd,8DAA8D;IAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAEzD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC5C,MAAM,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/C,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,UAAU,CACnC,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,MAAM,EACN,MAAM,CACP,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;KAC5B;IAED,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CACzC,SAAS,EACT,aAAa,EACb,SAAS,EACT,GAAG,EACH,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,IAAI,EACJ,MAAM,CACP,CAAC;IAEF,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,WAAW,EAAE,CAAC;AAC7C,CAAC;AA5DD,gCA4DC"}
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../src/analyze.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,gEAAkD;AAClD,qCAAqC;AAErC,2CAAgD;AAGhD,gEAAkD;AAClD,yDAA2C;AAC3C,6CAA+B;AAmC/B,KAAK,UAAU,4BAA4B,CACzC,MAA0B,EAC1B,MAAc;IAEd,sEAAsE;IACtE,oCAAoC;IACpC,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,IAAI,6BAAiB,CAAC,QAAQ,CAAC,EAAE;YAC/B,MAAM,CAAC,UAAU,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;YAC5C,MAAM,MAAM,CAAC,sBAAsB,CACjC,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,EACpD,QAAQ,CACT,CAAC;YACF,MAAM,CAAC,QAAQ,EAAE,CAAC;SACnB;KACF;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,MAA0B,EAC1B,MAAc;IAEd,MAAM,4BAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,MAAM,CAAC,UAAU,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,CAAC,gBAAgB,CAC3B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CACrD,CAAC;QACF,MAAM,CAAC,QAAQ,EAAE,CAAC;KACnB;AACH,CAAC;AAED,2DAA2D;AACpD,KAAK,UAAU,UAAU,CAC9B,WAAmB,EACnB,UAAkB,EAClB,eAAuB,EACvB,WAAmB,EACnB,MAA0B,EAC1B,MAAc;IAEd,MAAM,YAAY,GAAwB,EAAE,CAAC;IAE7C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,MAAM,CAAC,UAAU,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;QAE3C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/D,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,gDAAgD,CAC9E,CAAC;SACH;QAED,IAAI;YACF,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;gBACxC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC5B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;oBAEvC,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAC7C,MAAM,CAAC,OAAO,EACd,QAAQ,CACT,CAAC;oBACF,uEAAuE;oBACvE,2EAA2E;oBAC3E,MAAM,cAAc,GAAG,GAAG,YAAY,YAAY,IAAI,MAAM,CAAC;oBAC7D,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;yBACrC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;yBACnC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACd,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;oBACrD,MAAM,CAAC,KAAK,CACV,wBAAwB,QAAQ,QAAQ,kBAAkB,EAAE,CAC7D,CAAC;oBAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,QAAQ,IAAI,IAAI,QAAQ,CAAC,CAAC;oBAEtE,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;oBAC3C,MAAM,MAAM,CAAC,eAAe,CAC1B,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,eAAe,EACf,WAAW,CACZ,CAAC;oBAEF,MAAM,CAAC,KAAK,CACV,8BAA8B,QAAQ,gBAAgB,SAAS,GAAG,CACnE,CAAC;oBACF,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAElB,yBAAyB;oBACzB,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;oBACrC,YAAY,CAAC,WAAW,IAAI,YAAY,QAAQ,cAAc,CAAC;wBAC7D,OAAO,GAAG,SAAS,CAAC;iBACvB;aACF;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,YAAY,CAAC,wBAAwB,GAAG,QAAQ,CAAC;YACjD,OAAO,YAAY,CAAC;SACrB;KACF;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAxED,gCAwEC;AAEM,KAAK,UAAU,UAAU,CAC9B,aAA4B,EAC5B,SAAiB,EACjB,GAAW,EACX,WAA+B,EAC/B,YAAgC,EAChC,aAAiC,EACjC,YAAoB,EACpB,WAA+B,EAC/B,UAAkB,EAClB,SAAiB,EACjB,QAAiB,EACjB,IAAe,EACf,SAAiB,EACjB,UAAkB,EAClB,eAAuB,EACvB,WAAmB,EACnB,MAA0B,EAC1B,MAAc;IAEd,8DAA8D;IAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAEzD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC5C,MAAM,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/C,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,YAAY,GAAG,MAAM,UAAU,CACnC,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,MAAM,EACN,MAAM,CACP,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;KAC5B;IAED,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CACzC,SAAS,EACT,aAAa,EACb,SAAS,EACT,GAAG,EACH,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,IAAI,EACJ,MAAM,CACP,CAAC;IAEF,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,WAAW,EAAE,CAAC;AAC7C,CAAC;AA5DD,gCA4DC"}

9
lib/api-client.js generated
View File

@@ -10,8 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const githubUtils = __importStar(require("@actions/github/lib/utils"));
const retry = __importStar(require("@octokit/plugin-retry"));
const github = __importStar(require("@actions/github"));
const console_log_level_1 = __importDefault(require("console-log-level"));
const path = __importStar(require("path"));
const actions_util_1 = require("./actions-util");
@@ -20,12 +19,12 @@ exports.getApiClient = function (githubAuth, githubUrl, allowLocalRun = false) {
if (util_1.isLocalRun() && !allowLocalRun) {
throw new Error("Invalid API call in local run");
}
const retryingOctokit = githubUtils.GitHub.plugin(retry.retry);
return new retryingOctokit(githubUtils.getOctokitOptions(githubAuth, {
return new github.GitHub({
auth: githubAuth,
baseUrl: getApiUrl(githubUrl),
userAgent: "CodeQL Action",
log: console_log_level_1.default({ level: "debug" }),
}));
});
};
function getApiUrl(githubUrl) {
const url = new URL(githubUrl);

View File

@@ -1 +1 @@
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uEAAyD;AACzD,6DAA+C;AAC/C,0EAAgD;AAChD,2CAA6B;AAE7B,iDAAuE;AACvE,iCAAoC;AAEvB,QAAA,YAAY,GAAG,UAC1B,UAAkB,EAClB,SAAiB,EACjB,aAAa,GAAG,KAAK;IAErB,IAAI,iBAAU,EAAE,IAAI,CAAC,aAAa,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;KAClD;IACD,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,IAAI,eAAe,CACxB,WAAW,CAAC,iBAAiB,CAAC,UAAU,EAAE;QACxC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC;QAC7B,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,kDAAkD;IAClD,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,oFAAoF;AACpF,+CAA+C;AAC/C,SAAgB,mBAAmB,CAAC,aAAa,GAAG,KAAK;IACvD,OAAO,oBAAY,CACjB,+BAAgB,CAAC,OAAO,CAAC,EACzB,kCAAmB,CAAC,mBAAmB,CAAC,EACxC,aAAa,CACd,CAAC;AACJ,CAAC;AAND,kDAMC"}
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wDAA0C;AAC1C,0EAAgD;AAChD,2CAA6B;AAE7B,iDAAuE;AACvE,iCAAoC;AAEvB,QAAA,YAAY,GAAG,UAC1B,UAAkB,EAClB,SAAiB,EACjB,aAAa,GAAG,KAAK;IAErB,IAAI,iBAAU,EAAE,IAAI,CAAC,aAAa,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;KAClD;IACD,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC;QACvB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC;QAC7B,SAAS,EAAE,eAAe;QAC1B,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAE/B,kDAAkD;IAClD,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,oFAAoF;AACpF,+CAA+C;AAC/C,SAAgB,mBAAmB,CAAC,aAAa,GAAG,KAAK;IACvD,OAAO,oBAAY,CACjB,+BAAgB,CAAC,OAAO,CAAC,EACzB,kCAAmB,CAAC,mBAAmB,CAAC,EACxC,aAAa,CACd,CAAC;AACJ,CAAC;AAND,kDAMC"}

87
lib/codeql.js generated
View File

@@ -52,7 +52,7 @@ function getCodeQLActionRepository(mode) {
const relativeScriptPathParts = relativeScriptPath.split(path.sep);
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
}
async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
async function getCodeQLBundleDownloadURL(bundleNames, githubAuth, githubUrl, mode, logger) {
const codeQLActionRepository = getCodeQLActionRepository(mode);
const potentialDownloadSources = [
// This GitHub instance, and this Action.
@@ -67,10 +67,10 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
const uniqueDownloadSources = potentialDownloadSources.filter((url, index, self) => index === self.indexOf(url));
for (const downloadSource of uniqueDownloadSources) {
const [apiURL, repository] = downloadSource;
// If we've reached the final case, short-circuit the API check since we know the bundle exists and is public.
// If we've reached the final case, short-circuit the API check since we know the bundles exist and are public.
if (apiURL === util.GITHUB_DOTCOM_URL &&
repository === CODEQL_DEFAULT_ACTION_REPOSITORY) {
break;
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${bundleNames[0]}`;
}
const [repositoryOwner, repositoryName] = repository.split("/");
try {
@@ -81,8 +81,12 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
repo: repositoryName,
tag: CODEQL_BUNDLE_VERSION,
});
for (const asset of release.data.assets) {
if (asset.name === CODEQL_BUNDLE_NAME) {
// See if any of the bundles appears in the assets list
const assetMap = new Map(release.data.assets.map((x) => [x.name, x]));
for (const bundleName of bundleNames) {
logger.debug(`Looking for ${bundleName}`);
const asset = assetMap.get(bundleName);
if (asset) {
logger.info(`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`);
return asset.url;
}
@@ -94,6 +98,7 @@ async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
}
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${CODEQL_BUNDLE_NAME}`;
}
exports.getCodeQLBundleDownloadURL = getCodeQLBundleDownloadURL;
// 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) {
@@ -109,22 +114,75 @@ async function toolcacheDownloadTool(url, headers, tempDir, logger) {
await pipeline(response.message, fs.createWriteStream(dest));
return dest;
}
async function setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
async function setupCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
// Setting these two env vars makes the toolcache code safe to use outside,
// of actions but this is obviously not a great thing we're doing and it would
// be better to write our own implementation to use outside of actions.
process.env["RUNNER_TEMP"] = tempDir;
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
// The URL identifies the release version. E.g., codeql-20200901 .
// The plVersion identifies the platform-language combination of the package
// within the release. E.g., `linux64-cpp` in `codeql-linux64-cpp.tar.gz`.
// We expect the codeqlUrl (when given) to always point to the main bundle
// `codeql-bundle.tar.gz`
//
// The logic is as follows:
// - Always use the Toolcache if available.
// - If we would like a platform-language package, but have the
// full bundle in the cache, use that.
// - If codeqlURL is specified, use that.
// - If a single language is being analyzed, try to download the platform-language package.
// - If it is not available in the release assets, fallback to the full bundle
// - If multiple languages are being anlyzed, use the full bundle
let plVersion = undefined;
let platform;
if (process.platform === "win32") {
platform = "win64";
}
else if (process.platform === "linux") {
platform = "linux64";
}
else if (process.platform === "darwin") {
platform = "osx64";
}
else {
throw new Error(`Unsupported platform: ${process.platform}`);
}
if (languages.length === 1) {
plVersion = `${platform}-${languages[0]}`;
}
try {
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, logger);
let codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
if (codeqlFolder) {
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
}
else {
if (!codeqlURL) {
codeqlURL = await getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger);
let codeqlFolder;
logger.debug(`PL Version ${plVersion}`);
if (plVersion) {
codeqlFolder = toolcache.find("CodeQL", `${codeqlURLVersion}-${plVersion}`);
if (codeqlFolder) {
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
}
}
if (!codeqlFolder) {
codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
if (codeqlFolder) {
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
}
}
if (!codeqlFolder) {
const codeqlToolcacheVersion = plVersion
? `${codeqlURLVersion}-${plVersion}`
: codeqlURLVersion;
logger.debug(`CodeQL not found in cache`);
if (!codeqlURL) {
// Provide a few options, from smaller to bigger
const bundles = [];
if (plVersion) {
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${plVersion}`));
}
bundles.push(CODEQL_BUNDLE_NAME.replace("-bundle", `-bundle-${platform}`));
bundles.push(CODEQL_BUNDLE_NAME);
codeqlURL = await getCodeQLBundleDownloadURL(bundles, githubAuth, githubUrl, mode, logger);
}
logger.debug(`Using CodeQL URL: ${codeqlURL}`);
const headers = { accept: "application/octet-stream" };
// We only want to provide an authorization header if we are downloading
// from the same GitHub instance the Action is running on.
@@ -140,7 +198,8 @@ async function setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir,
const codeqlPath = await toolcacheDownloadTool(codeqlURL, headers, tempDir, logger);
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLVersion);
logger.debug(`Caching ${codeqlToolcacheVersion}`);
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlToolcacheVersion);
}
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
if (process.platform === "win32") {

File diff suppressed because one or more lines are too long

129
lib/codeql.test.js generated
View File

@@ -10,30 +10,146 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const github = __importStar(require("@actions/github"));
const toolcache = __importStar(require("@actions/tool-cache"));
const ava_1 = __importDefault(require("ava"));
const nock_1 = __importDefault(require("nock"));
const path = __importStar(require("path"));
const sinon_1 = __importDefault(require("sinon"));
const api = __importStar(require("./api-client"));
const codeql = __importStar(require("./codeql"));
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
const languages_1 = require("./languages");
const logging_1 = require("./logging");
const testing_utils_1 = require("./testing-utils");
const util = __importStar(require("./util"));
testing_utils_1.setupTests(ava_1.default);
ava_1.default("download codeql bundle cache", async (t) => {
ava_1.default("download and populate codeql bundle cache", async (t) => {
await util.withTmpDir(async (tmpDir) => {
const versions = ["20200601", "20200610"];
const languages = [
[languages_1.Language.cpp],
[languages_1.Language.cpp, languages_1.Language.python],
];
const platform = process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: process.platform === "darwin"
? "osx64"
: undefined;
for (let i = 0; i < versions.length; i++) {
const version = versions[i];
nock_1.default("https://example.com")
.get(`/download/codeql-bundle-${version}/codeql-bundle.tar.gz`)
for (let j = 0; j < languages.length; j++) {
const version = versions[i];
const plVersion = languages[j].length === 1
? `${platform}-${languages[j][0]}`
: undefined;
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`, languages[j], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
const toolcacheVersion = plVersion
? `0.0.0-${version}-${plVersion}`
: `0.0.0-${version}`;
t.assert(toolcache.find("CodeQL", toolcacheVersion), `Looking for ${toolcacheVersion}`);
}
}
const cachedVersions = toolcache.findAllVersions("CodeQL");
// We should now have 4 cached versions: e.g.,
// 20200601, 20200601-linux64-cpp, 20200610, 20200610-linux64-cpp
t.is(cachedVersions.length, 4);
});
});
ava_1.default("download small codeql bundle if analyzing only one language", async (t) => {
// Note: We do not specify a codeqlURL in this test, thus testing that
// the logic for constructing the URL takes into account the
// language being analyzed
await util.withTmpDir(async (tmpDir) => {
const languages = [
[languages_1.Language.cpp],
[languages_1.Language.cpp, languages_1.Language.python],
];
const platform = process.platform === "win32"
? "win64"
: process.platform === "linux"
? "linux64"
: process.platform === "darwin"
? "osx64"
: undefined;
for (let i = 0; i < languages.length; i++) {
const plVersion = languages[i].length === 1
? `${platform}-${languages[i][0]}`
: undefined;
const pkg = plVersion
? `codeql-bundle-${plVersion}.tar.gz`
: "codeql-bundle.tar.gz";
// Mock the API client
const client = new github.GitHub("123");
const response = {
data: {
assets: [
{
name: `codeql-bundle-${platform}-cpp.tar.gz`,
url: `https://github.example.com/url/codeql-bundle-${platform}-cpp.tar.gz`,
},
{
name: "codeql-bundle.tar.gz",
url: "https://github.example.com/url/codeql-bundle.tar.gz",
},
],
},
};
sinon_1.default.stub(client.repos, "getReleaseByTag").resolves(response);
sinon_1.default.stub(api, "getApiClient").value(() => client);
nock_1.default("https://github.example.com")
.get(`/url/${pkg}`)
.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`, "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
await codeql.setupCodeQL(undefined, languages[i], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
const parsedVersion = codeql.getCodeQLURLVersion(`/${defaults.bundleVersion}/`, logging_1.getRunnerLogger(true));
const toolcacheVersion = plVersion
? `${parsedVersion}-${plVersion}`
: parsedVersion;
t.assert(toolcache.find("CodeQL", toolcacheVersion), `Looking for ${toolcacheVersion} - ${plVersion}`);
}
const cachedVersions = toolcache.findAllVersions("CodeQL");
t.is(cachedVersions.length, 2);
});
});
ava_1.default("use full codeql bundle cache if smaller bundle is not available", async (t) => {
// If we look for a platform-language version but find the full bundle in the cache,
// we use the full bundle
await util.withTmpDir(async (tmpDir) => {
const version = "20200601";
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`, [], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
t.is(toolcache.findAllVersions("CodeQL").length, 1);
// Now try to request the cpp version, and see that we do not change the cache
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, [languages_1.Language.cpp], "token", "https://github.example.com", tmpDir, tmpDir, "runner", logging_1.getRunnerLogger(true));
t.assert(toolcache.find("CodeQL", `0.0.0-${version}`));
t.is(toolcache.findAllVersions("CodeQL").length, 1);
});
});
ava_1.default("use larger bundles if smaller ones are not released", async (t) => {
// Mock the API client
const client = new github.GitHub("123");
const response = {
data: {
assets: [{ name: "full-bundle", url: "url/file.gz" }],
},
};
const getReleaseByTagMock = sinon_1.default
.stub(client.repos, "getReleaseByTag")
.resolves(response);
sinon_1.default.stub(api, "getApiClient").value(() => client);
// Setting this env is required by a dependency of getCodeQLBundleDownloadURL
process.env["RUNNER_TEMP"] = "abc";
const codeqlURL = await codeql.getCodeQLBundleDownloadURL(["small-bundle", "full-bundle"], "", "", "actions", logging_1.getRunnerLogger(true));
t.deepEqual(codeqlURL, "url/file.gz");
t.assert(getReleaseByTagMock.called);
});
ava_1.default("parse codeql bundle url version", (t) => {
const tests = {
"20200601": "0.0.0-20200601",
@@ -42,6 +158,7 @@ ava_1.default("parse codeql bundle url version", (t) => {
"1.2.3": "1.2.3",
"1.2.3-alpha": "1.2.3-alpha",
"1.2.3-beta.1": "1.2.3-beta.1",
"20200601-linux64-python": "0.0.0-20200601-linux64-python",
};
for (const [version, expectedVersion] of Object.entries(tests)) {
const url = `https://github.com/.../codeql-bundle-${version}/...`;

File diff suppressed because one or more lines are too long

101
lib/config-utils.js generated
View File

@@ -12,7 +12,6 @@ const yaml = __importStar(require("js-yaml"));
const path = __importStar(require("path"));
const api = __importStar(require("./api-client"));
const externalQueries = __importStar(require("./external-queries"));
const languages_1 = require("./languages");
// Property names from the user-supplied config file.
const NAME_PROPERTY = "name";
const DISABLE_DEFAULT_QUERIES_PROPERTY = "disable-default-queries";
@@ -289,84 +288,6 @@ function getConfigFilePropertyError(configFile, property, error) {
return `The configuration file "${configFile}" is invalid: property "${property}" ${error}`;
}
}
function getNoLanguagesError() {
return ("Did not detect any languages to analyze. " +
"Please update input in workflow or check that GitHub detects the correct languages in your repository.");
}
exports.getNoLanguagesError = getNoLanguagesError;
function getUnknownLanguagesError(languages) {
return `Did not recognise the following languages: ${languages.join(", ")}`;
}
exports.getUnknownLanguagesError = getUnknownLanguagesError;
/**
* Gets the set of languages in the current repository
*/
async function getLanguagesInRepo(repository, githubAuth, githubUrl, logger) {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api
.getApiClient(githubAuth, githubUrl, true)
.repos.listLanguages({
owner: repository.owner,
repo: repository.repo,
});
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
// The GitHub API is going to return languages in order of popularity,
// When we pick a language to autobuild we want to pick the most popular traced language
// Since sets in javascript maintain insertion order, using a set here and then splatting it
// into an array gives us an array of languages ordered by popularity
const languages = new Set();
for (const lang of Object.keys(response.data)) {
const parsedLang = languages_1.parseLanguage(lang);
if (parsedLang !== undefined) {
languages.add(parsedLang);
}
}
return [...languages];
}
/**
* Get the languages to analyse.
*
* The result is obtained from the action input parameter 'languages' if that
* has been set, otherwise it is deduced as all languages in the repo that
* can be analysed.
*
* If no languages could be detected from either the workflow or the repository
* then throw an error.
*/
async function getLanguages(languagesInput, repository, githubAuth, githubUrl, logger) {
// Obtain from action input 'languages' if set
let languages = (languagesInput || "")
.split(",")
.map((x) => x.trim())
.filter((x) => x.length > 0);
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
if (languages.length === 0) {
// Obtain languages as all languages in the repo that can be analysed
languages = await getLanguagesInRepo(repository, githubAuth, githubUrl, logger);
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
}
// If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error.
if (languages.length === 0) {
throw new Error(getNoLanguagesError());
}
// Make sure they are supported
const parsedLanguages = [];
const unknownLanguages = [];
for (const language of languages) {
const parsedLanguage = languages_1.parseLanguage(language);
if (parsedLanguage === undefined) {
unknownLanguages.push(language);
}
else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
parsedLanguages.push(parsedLanguage);
}
}
if (unknownLanguages.length > 0) {
throw new Error(getUnknownLanguagesError(unknownLanguages));
}
return parsedLanguages;
}
async function addQueriesFromWorkflow(codeQL, queriesInput, languages, resultMap, tempDir, checkoutPath, githubUrl, logger) {
queriesInput = queriesInput.trim();
// "+" means "don't override config file" - see shouldAddConfigFileQueries
@@ -388,8 +309,7 @@ function shouldAddConfigFileQueries(queriesInput) {
/**
* Get the default config for when the user has not supplied one.
*/
async function getDefaultConfig(languagesInput, queriesInput, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
async function getDefaultConfig(languages, queriesInput, tempDir, toolCacheDir, codeQL, checkoutPath, githubUrl, logger) {
const queries = {};
await addDefaultQueries(codeQL, languages, queries);
if (queriesInput) {
@@ -410,7 +330,7 @@ exports.getDefaultConfig = getDefaultConfig;
/**
* Load the config from the given file.
*/
async function loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
async function loadConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
let parsedYAML;
if (isLocal(configFile)) {
// Treat the config file as relative to the workspace
@@ -430,7 +350,6 @@ async function loadConfig(languagesInput, queriesInput, configFile, repository,
throw new Error(getNameInvalid(configFile));
}
}
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
const queries = {};
const pathsIgnore = [];
const paths = [];
@@ -468,23 +387,23 @@ async function loadConfig(languagesInput, queriesInput, configFile, repository,
if (!(parsedYAML[PATHS_IGNORE_PROPERTY] instanceof Array)) {
throw new Error(getPathsIgnoreInvalid(configFile));
}
for (const path of parsedYAML[PATHS_IGNORE_PROPERTY]) {
parsedYAML[PATHS_IGNORE_PROPERTY].forEach((path) => {
if (typeof path !== "string" || path === "") {
throw new Error(getPathsIgnoreInvalid(configFile));
}
pathsIgnore.push(validateAndSanitisePath(path, PATHS_IGNORE_PROPERTY, configFile, logger));
}
});
}
if (PATHS_PROPERTY in parsedYAML) {
if (!(parsedYAML[PATHS_PROPERTY] instanceof Array)) {
throw new Error(getPathsInvalid(configFile));
}
for (const path of parsedYAML[PATHS_PROPERTY]) {
parsedYAML[PATHS_PROPERTY].forEach((path) => {
if (typeof path !== "string" || path === "") {
throw new Error(getPathsInvalid(configFile));
}
paths.push(validateAndSanitisePath(path, PATHS_PROPERTY, configFile, logger));
}
});
}
// The list of queries should not be empty for any language. If it is then
// it is a user configuration error.
@@ -513,15 +432,15 @@ async function loadConfig(languagesInput, queriesInput, configFile, repository,
* 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, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
async function initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
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, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
config = await getDefaultConfig(languages, queriesInput, tempDir, toolCacheDir, codeQL, checkoutPath, githubUrl, logger);
}
else {
config = await loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
config = await loadConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
}
// Save the config so we can easily access it again in the future
await saveConfig(config, logger);
@@ -556,7 +475,7 @@ async function getRemoteConfig(configFile, githubAuth, githubUrl) {
}
const response = await api
.getApiClient(githubAuth, githubUrl, true)
.repos.getContent({
.repos.getContents({
owner: pieces.groups.owner,
repo: pieces.groups.repo,
path: pieces.groups.path,

File diff suppressed because one or more lines are too long

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

@@ -31,19 +31,19 @@ function createConfigFile(inputFileContents, tmpDir) {
}
function mockGetContents(content) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
const client = new github.GitHub("123");
const response = {
data: content,
};
const spyGetContents = sinon_1.default
.stub(client.repos, "getContent")
.stub(client.repos, "getContents")
.resolves(response);
sinon_1.default.stub(api, "getApiClient").value(() => client);
return spyGetContents;
}
function mockListLanguages(languages) {
// Passing an auth token is required, so we just use a dummy value
const client = github.getOctokit("123");
const client = new github.GitHub("123");
const response = {
data: {},
};
@@ -56,7 +56,7 @@ function mockListLanguages(languages) {
ava_1.default("load empty config", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const logger = logging_1.getRunnerLogger(true);
const languages = "javascript,python";
const languages = [languages_1.Language.javascript, languages_1.Language.python];
const codeQL = codeql_1.setCodeQL({
async resolveQueries() {
return {
@@ -66,8 +66,8 @@ ava_1.default("load empty config", async (t) => {
};
},
});
const config = await configUtils.initConfig(languages, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger));
const config = await configUtils.initConfig(languages, undefined, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, tmpDir, tmpDir, codeQL, tmpDir, "https://github.example.com", logger));
});
});
ava_1.default("loading config saves config", async (t) => {
@@ -86,7 +86,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, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logger);
const config1 = await configUtils.initConfig([languages_1.Language.javascript, languages_1.Language.python], undefined, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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
@@ -97,7 +97,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", { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig([], undefined, "../input", tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -110,7 +110,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, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig([], undefined, configFile, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -120,11 +120,11 @@ ava_1.default("load non-local input with invalid repo syntax", async (t) => {
});
ava_1.default("load non-existent input", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const languages = "javascript";
const languages = [languages_1.Language.javascript];
const configFile = "input";
t.false(fs.existsSync(path.join(tmpDir, configFile)));
try {
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -182,9 +182,9 @@ ava_1.default("load non-empty input", async (t) => {
toolCacheDir: tmpDir,
codeQLCmd: codeQL.getPath(),
};
const languages = "javascript";
const languages = [languages_1.Language.javascript];
const configFilePath = createConfigFile(inputFileContents, tmpDir);
const actualConfig = await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const actualConfig = await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
// Should exactly equal the object we constructed earlier
t.deepEqual(actualConfig, expectedConfig);
});
@@ -218,9 +218,9 @@ ava_1.default("Default queries are used", async (t) => {
paths:
- foo`;
fs.mkdirSync(path.join(tmpDir, "foo"));
const languages = "javascript";
const languages = [languages_1.Language.javascript];
const configFilePath = createConfigFile(inputFileContents, tmpDir);
await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
// Check resolve queries was called correctly
t.deepEqual(resolveQueriesArgs.length, 1);
t.deepEqual(resolveQueriesArgs[0].queries, [
@@ -236,9 +236,9 @@ ava_1.default("Default queries are used", async (t) => {
*/
function queriesToResolvedQueryForm(queries) {
const dummyResolvedQueries = {};
for (const q of queries) {
queries.forEach((q) => {
dummyResolvedQueries[q] = {};
}
});
return {
byLanguage: {
javascript: dummyResolvedQueries,
@@ -262,8 +262,8 @@ ava_1.default("Queries can be specified in config file", async (t) => {
return queriesToResolvedQueryForm(queries);
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
const config = await configUtils.initConfig(languages, undefined, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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.
@@ -295,8 +295,8 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
return queriesToResolvedQueryForm(queries);
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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.
@@ -327,8 +327,8 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
return queriesToResolvedQueryForm(queries);
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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
@@ -353,8 +353,8 @@ ava_1.default("Multiple queries can be specified in workflow file, no config fil
return queriesToResolvedQueryForm(queries);
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, queries, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
const config = await configUtils.initConfig(languages, queries, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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
@@ -392,8 +392,8 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
return queriesToResolvedQueryForm(queries);
},
});
const languages = "javascript";
const config = await configUtils.initConfig(languages, queries, configFilePath, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
const config = await configUtils.initConfig(languages, queries, configFilePath, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", 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,
@@ -417,7 +417,7 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
ava_1.default("Invalid queries in workflow file handled correctly", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const queries = "foo/bar@v1@v3";
const languages = "javascript";
const languages = [languages_1.Language.javascript];
// This function just needs to be type-correct; it doesn't need to do anything,
// since we're deliberately passing in invalid data
const codeQL = codeql_1.setCodeQL({
@@ -432,7 +432,7 @@ ava_1.default("Invalid queries in workflow file handled correctly", async (t) =>
},
});
try {
await configUtils.initConfig(languages, queries, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, queries, undefined, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
t.fail("initConfig did not throw error");
}
catch (err) {
@@ -474,8 +474,8 @@ ava_1.default("API client used when reading remote config", async (t) => {
// Create checkout directory for remote queries repository
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, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
const languages = [languages_1.Language.javascript];
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
t.assert(spyGetContents.called);
});
});
@@ -485,7 +485,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, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig([], undefined, repoReference, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -501,7 +501,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, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig([], undefined, repoReference, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
@@ -510,28 +510,24 @@ 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([]);
try {
await configUtils.initConfig(undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
t.deepEqual(err, new Error(configUtils.getNoLanguagesError()));
}
});
mockListLanguages([]);
try {
await languages_1.getLanguages(undefined, { owner: "github", repo: "example " }, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
t.deepEqual(err, new Error(languages_1.getNoLanguagesError()));
}
});
ava_1.default("Unknown languages", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
const languages = "ruby,english";
try {
await configUtils.initConfig(languages, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(["ruby", "english"])));
}
});
const languages = "ruby,english";
try {
await languages_1.getLanguages(languages, { owner: "github", repo: "example " }, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {
t.deepEqual(err, new Error(languages_1.getUnknownLanguagesError(["ruby", "english"])));
}
});
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
ava_1.default(`load invalid input - ${testName}`, async (t) => {
@@ -545,12 +541,12 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
};
},
});
const languages = "javascript";
const languages = [languages_1.Language.javascript];
const configFile = "input";
const inputFile = path.join(tmpDir, configFile);
fs.writeFileSync(inputFile, inputFileContents, "utf8");
try {
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
await configUtils.initConfig(languages, undefined, configFile, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
throw new Error("initConfig did not throw error");
}
catch (err) {

File diff suppressed because one or more lines are too long

8
lib/fingerprints.js generated
View File

@@ -229,16 +229,14 @@ function addFingerprints(sarifContents, checkoutPath, logger) {
}
}
// Now hash each file that was found
for (const [filepath, callbacks] of Object.entries(callbacksByFile)) {
Object.entries(callbacksByFile).forEach(([filepath, callbacks]) => {
// A callback that forwards the hash to all other callbacks for that file
const teeCallback = function (lineNumber, hash) {
for (const c of Object.values(callbacks)) {
c(lineNumber, hash);
}
Object.values(callbacks).forEach((c) => c(lineNumber, hash));
};
const fileContents = fs.readFileSync(filepath).toString();
hash(teeCallback, fileContents);
}
});
return JSON.stringify(sarif);
}
exports.addFingerprints = addFingerprints;

File diff suppressed because one or more lines are too long

17
lib/init-action.js generated
View File

@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const actionsUtil = __importStar(require("./actions-util"));
const init_1 = require("./init");
const languages_1 = require("./languages");
const logging_1 = require("./logging");
const repository_1 = require("./repository");
async function sendSuccessStatusReport(startedAt, config) {
@@ -54,14 +55,10 @@ async function run() {
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "starting", startedAt), true))) {
return;
}
codeql = await init_1.initCodeQL(actionsUtil.getOptionalInput("tools"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), "actions", logger);
config = await init_1.initConfig(actionsUtil.getOptionalInput("languages"), actionsUtil.getOptionalInput("queries"), actionsUtil.getOptionalInput("config-file"), repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
try {
await init_1.installPythonDeps(codeql, logger);
}
catch (err) {
logger.warning(`${err.message} You can call this action with 'setup-python-dependencies: false' to disable this process`);
}
const repositoryNWO = repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY"));
const languages = await languages_1.getLanguages(actionsUtil.getOptionalInput("languages"), repositoryNWO, actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
codeql = await init_1.initCodeQL(actionsUtil.getOptionalInput("tools"), languages, actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), "actions", logger);
config = await init_1.initConfig(languages, actionsUtil.getOptionalInput("queries"), actionsUtil.getOptionalInput("config-file"), actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), logger);
}
catch (e) {
core.setFailed(e.message);
@@ -81,9 +78,7 @@ async function run() {
core.exportVariable("CODEQL_RAM", codeqlRam);
const tracerConfig = await init_1.runInit(codeql, config);
if (tracerConfig !== undefined) {
for (const [key, value] of Object.entries(tracerConfig.env)) {
core.exportVariable(key, value);
}
Object.entries(tracerConfig.env).forEach(([key, value]) => core.exportVariable(key, value));
if (process.platform === "win32") {
await init_1.injectWindowsTracer("Runner.Worker.exe", undefined, config, codeql, tracerConfig);
}

View File

@@ -1 +1 @@
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAG9C,iCAMgB;AAChB,uCAA6C;AAC7C,6CAAkD;AAkBlD,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,MAA0B;;IAE1B,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,MAAM,EACN,SAAS,EACT,SAAS,CACV,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CACvE,GAAG,CACJ,CAAC;IACF,MAAM,qBAAqB,GAAG,MAAM,CAAC,iBAAiB,CACpD,yBAAyB,CAC1B;QACC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,YAAY,SAAG,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,0CAAE,IAAI,EAAE,CAAC;IACnE,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QAC9D,OAAO,CAAC,IAAI,CACV,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC/D,CAAC;KACH;IACD,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,YAAY,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;YACzC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;YACxB,CAAC,CAAC,YAAY,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KAC1C;IAED,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,SAAS;QACT,kBAAkB,EAAE,iBAAiB,IAAI,EAAE;QAC3C,KAAK;QACL,YAAY,EAAE,WAAW;QACzB,uBAAuB,EAAE,qBAAqB;QAC9C,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;KAC3B,CAAC;IAEF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,IAAI,MAA0B,CAAC;IAC/B,IAAI,MAAc,CAAC;IAEnB,IAAI;QACF,WAAW,CAAC,0BAA0B,EAAE,CAAC;QACzC,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EACvE,IAAI,CACL,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,GAAG,MAAM,iBAAU,CACvB,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,EACrC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,EACrC,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,EACpD,WAAW,CAAC,mBAAmB,CAAC,aAAa,CAAC,EAC9C,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,EACpD,SAAS,EACT,MAAM,CACP,CAAC;QACF,MAAM,GAAG,MAAM,iBAAU,CACvB,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,EACzC,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,EACvC,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAC3C,+BAAkB,CAAC,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,EACxE,WAAW,CAAC,mBAAmB,CAAC,aAAa,CAAC,EAC9C,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,EACpD,MAAM,EACN,WAAW,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EACnD,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,EACrC,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,EACpD,MAAM,CACP,CAAC;QAEF,IAAI;YACF,MAAM,wBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACzC;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,CAAC,OAAO,CACZ,GAAG,GAAG,CAAC,OAAO,2FAA2F,CAC1G,CAAC;SACH;KACF;IAAC,OAAO,CAAC,EAAE;QACV,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,MAAM,WAAW,CAAC,gBAAgB,CAChC,MAAM,WAAW,CAAC,sBAAsB,CACtC,MAAM,EACN,SAAS,EACT,SAAS,EACT,CAAC,CAAC,OAAO,CACV,CACF,CAAC;QACF,OAAO;KACR;IAED,IAAI;QACF,mBAAmB;QACnB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO,CACV,6GAA6G,CAC9G,CAAC;SACH;QAED,mGAAmG;QACnG,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC;QACtD,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAE7C,MAAM,YAAY,GAAG,MAAM,cAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,YAAY,KAAK,SAAS,EAAE;YAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;gBAC3D,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aACjC;YAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;gBAChC,MAAM,0BAAmB,CACvB,mBAAmB,EACnB,SAAS,EACT,MAAM,EACN,MAAM,EACN,YAAY,CACb,CAAC;aACH;SACF;KACF;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,MAAM,EACN,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;KACR;IACD,MAAM,uBAAuB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAChB,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}

39
lib/init.js generated
View File

@@ -15,17 +15,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, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
async function initCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
logger.startGroup("Setup CodeQL tools");
const codeql = await codeql_1.setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger);
const codeql = await codeql_1.setupCodeQL(codeqlURL, languages, githubAuth, githubUrl, tempDir, toolsDir, mode, logger);
await codeql.printVersion();
logger.endGroup();
return codeql;
}
exports.initCodeQL = initCodeQL;
async function initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
async function initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
logger.startGroup("Load language configuration");
const config = await configUtils.initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
const config = await configUtils.initConfig(languages, queriesInput, configFile, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
analysisPaths.printPathFiltersWarning(config, logger);
logger.endGroup();
return config;
@@ -121,35 +121,4 @@ async function injectWindowsTracer(processName, processLevel, config, codeql, tr
], { env: { ODASA_TRACER_CONFIGURATION: tracerConfig.spec } }).exec();
}
exports.injectWindowsTracer = injectWindowsTracer;
async function installPythonDeps(codeql, logger) {
logger.startGroup("Setup Python dependencies");
if (process.platform !== "linux") {
logger.info("Currently, auto-installing python dependancies is only supported on linux");
logger.endGroup();
return;
}
const scriptsFolder = path.resolve(__dirname, "../python-setup");
// Setup tools on the Github hosted runners
if (process.env["ImageOS"] !== undefined) {
try {
await new toolrunnner.ToolRunner(path.join(scriptsFolder, "install_tools.sh")).exec();
}
catch (e) {
// This script tries to install some needed tools in the runner. It should not fail, but if it does
// we just abort the process without failing the action
logger.endGroup();
logger.warning("Unable to download and extract the tools needed for installing the python dependecies. You can call this action with 'setup-python-dependencies: false' to disable this process.");
}
}
// Install dependencies
try {
await new toolrunnner.ToolRunner(path.join(scriptsFolder, "auto_install_packages.py"), [path.dirname(codeql.getPath())]).exec();
}
catch (e) {
logger.endGroup();
logger.warning("We were unable to install your python dependencies. You can call this action with 'setup-python-dependencies: false' to disable this process.");
}
logger.endGroup();
}
exports.installPythonDeps = installPythonDeps;
//# sourceMappingURL=init.js.map

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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"}

87
lib/languages.js generated
View File

@@ -1,5 +1,13 @@
"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 api = __importStar(require("./api-client"));
// All the languages supported by CodeQL
var Language;
(function (Language) {
@@ -40,4 +48,83 @@ function isScannedLanguage(language) {
return !isTracedLanguage(language);
}
exports.isScannedLanguage = isScannedLanguage;
function getNoLanguagesError() {
return ("Did not detect any languages to analyze. " +
"Please update input in workflow or check that GitHub detects the correct languages in your repository.");
}
exports.getNoLanguagesError = getNoLanguagesError;
function getUnknownLanguagesError(languages) {
return `Did not recognise the following languages: ${languages.join(", ")}`;
}
exports.getUnknownLanguagesError = getUnknownLanguagesError;
/**
* Get the languages to analyse.
*
* The result is obtained from the action input parameter 'languages' if that
* has been set, otherwise it is deduced as all languages in the repo that
* can be analysed.
*
* If no languages could be detected from either the workflow or the repository
* then throw an error.
*/
async function getLanguages(languagesInput, repository, githubAuth, githubUrl, logger) {
// Obtain from action input 'languages' if set
let languages = (languagesInput || "")
.split(",")
.map((x) => x.trim())
.filter((x) => x.length > 0);
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
if (languages.length === 0) {
// Obtain languages as all languages in the repo that can be analysed
languages = await getLanguagesInRepo(repository, githubAuth, githubUrl, logger);
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
}
// If the languages parameter was not given and no languages were
// detected then fail here as this is a workflow configuration error.
if (languages.length === 0) {
throw new Error(getNoLanguagesError());
}
// Make sure they are supported
const parsedLanguages = [];
const unknownLanguages = [];
for (const language of languages) {
const parsedLanguage = parseLanguage(language);
if (parsedLanguage === undefined) {
unknownLanguages.push(language);
}
else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
parsedLanguages.push(parsedLanguage);
}
}
if (unknownLanguages.length > 0) {
throw new Error(getUnknownLanguagesError(unknownLanguages));
}
return parsedLanguages;
}
exports.getLanguages = getLanguages;
/**
* Gets the set of languages in the current repository
*/
async function getLanguagesInRepo(repository, githubAuth, githubUrl, logger) {
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
const response = await api
.getApiClient(githubAuth, githubUrl, true)
.repos.listLanguages({
owner: repository.owner,
repo: repository.repo,
});
logger.debug(`Languages API response: ${JSON.stringify(response)}`);
// The GitHub API is going to return languages in order of popularity,
// When we pick a language to autobuild we want to pick the most popular traced language
// Since sets in javascript maintain insertion order, using a set here and then splatting it
// into an array gives us an array of languages ordered by popularity
const languages = new Set();
for (const lang of Object.keys(response.data)) {
const parsedLang = parseLanguage(lang);
if (parsedLang !== undefined) {
languages.add(parsedLang);
}
}
return [...languages];
}
//# sourceMappingURL=languages.js.map

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,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC;AAFD,4CAEC;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":"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"}

11
lib/runner.js generated
View File

@@ -61,9 +61,7 @@ function importTracerEnvironment(config) {
if (!("ODASA_TRACER_CONFIGURATION" in process.env)) {
const jsonEnvFile = path.join(config.tempDir, codeqlEnvJsonFilename);
const env = JSON.parse(fs.readFileSync(jsonEnvFile).toString("utf-8"));
for (const key of Object.keys(env)) {
process.env[key] = env[key];
}
Object.keys(env).forEach((key) => (process.env[key] = env[key]));
}
}
// Allow the user to specify refs in full refs/heads/branch format
@@ -121,14 +119,17 @@ program
logger.info(`Cleaning temp directory ${tempDir}`);
fs.rmdirSync(tempDir, { recursive: true });
fs.mkdirSync(tempDir, { recursive: true });
const githubUrl = parseGithubUrl(cmd.githubUrl);
const repositoryNWO = repository_1.parseRepositoryNwo(cmd.repository);
const languages = await languages_1.getLanguages(cmd.languages, repositoryNWO, cmd.githubAuth, githubUrl, logger);
let codeql;
if (cmd.codeqlPath !== undefined) {
codeql = codeql_1.getCodeQL(cmd.codeqlPath);
}
else {
codeql = await init_1.initCodeQL(undefined, cmd.githubAuth, parseGithubUrl(cmd.githubUrl), tempDir, toolsDir, "runner", logger);
codeql = await init_1.initCodeQL(undefined, languages, cmd.githubAuth, githubUrl, tempDir, toolsDir, "runner", logger);
}
const config = await init_1.initConfig(cmd.languages, cmd.queries, cmd.configFile, repository_1.parseRepositoryNwo(cmd.repository), tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), cmd.githubAuth, parseGithubUrl(cmd.githubUrl), logger);
const config = await init_1.initConfig(languages, cmd.queries, cmd.configFile, tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), cmd.githubAuth, parseGithubUrl(cmd.githubUrl), logger);
const tracerConfig = await init_1.runInit(codeql, config);
if (tracerConfig === undefined) {
return;

File diff suppressed because one or more lines are too long

62
lib/upload-lib.js generated
View File

@@ -50,17 +50,50 @@ async function uploadPayload(payload, repositoryNwo, githubAuth, githubUrl, mode
if (testMode) {
return;
}
// Make up to 4 attempts to upload, and sleep for these
// number of seconds between each attempt.
// We don't want to backoff too much to avoid wasting action
// minutes, but just waiting a little bit could maybe help.
const backoffPeriods = [1, 5, 15];
const client = api.getApiClient(githubAuth, githubUrl);
const reqURL = mode === "actions"
? "PUT /repos/:owner/:repo/code-scanning/analysis"
: "POST /repos/:owner/:repo/code-scanning/sarifs";
const response = await client.request(reqURL, {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
});
logger.debug(`response status: ${response.status}`);
logger.info("Successfully uploaded results");
for (let attempt = 0; attempt <= backoffPeriods.length; attempt++) {
const reqURL = mode === "actions"
? "PUT /repos/:owner/:repo/code-scanning/analysis"
: "POST /repos/:owner/:repo/code-scanning/sarifs";
const response = await client.request(reqURL, {
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
data: payload,
});
logger.debug(`response status: ${response.status}`);
const statusCode = response.status;
if (statusCode === 202) {
logger.info("Successfully uploaded results");
return;
}
const requestID = response.headers["x-github-request-id"];
// On any other status code that's not 5xx mark the upload as failed
if (!statusCode || statusCode < 500 || statusCode >= 600) {
throw new Error(`Upload failed (${requestID}): (${statusCode}) ${JSON.stringify(response.data)}`);
}
// On a 5xx status code we may retry the request
if (attempt < backoffPeriods.length) {
// Log the failure as a warning but don't mark the action as failed yet
logger.warning(`Upload attempt (${attempt + 1} of ${backoffPeriods.length + 1}) failed (${requestID}). Retrying in ${backoffPeriods[attempt]} seconds: (${statusCode}) ${JSON.stringify(response.data)}`);
// Sleep for the backoff period
await new Promise((r) => setTimeout(r, backoffPeriods[attempt] * 1000));
continue;
}
else {
// If the upload fails with 5xx then we assume it is a temporary problem
// and not an error that the user has caused or can fix.
// We avoid marking the job as failed to avoid breaking CI workflows.
throw new Error(`Upload failed (${requestID}): (${statusCode}) ${JSON.stringify(response.data)}`);
}
}
// This case shouldn't ever happen as the final iteration of the loop
// will always throw an error instead of exiting to here.
throw new Error("Upload failed");
}
// Uploads a single sarif file or a directory of sarif files
// depending on what the path happens to refer to.
@@ -71,13 +104,10 @@ async function upload(sarifPath, repositoryNwo, commitOid, ref, analysisKey, ana
throw new Error(`Path does not exist: ${sarifPath}`);
}
if (fs.lstatSync(sarifPath).isDirectory()) {
const paths = fs
.readdirSync(sarifPath)
fs.readdirSync(sarifPath)
.filter((f) => f.endsWith(".sarif"))
.map((f) => path.resolve(sarifPath, f));
for (const path of paths) {
sarifFiles.push(path);
}
.map((f) => path.resolve(sarifPath, f))
.forEach((f) => sarifFiles.push(f));
if (sarifFiles.length === 0) {
throw new Error(`No SARIF files found to upload in "${sarifPath}".`);
}

File diff suppressed because one or more lines are too long

1
node_modules/.bin/which generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../which/bin/which

View File

@@ -4,7 +4,7 @@
## Usage
Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners) and correctly sets GHES base urls. See https://octokit.github.io/rest.js for the API.
Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners). See https://octokit.github.io/rest.js for the API.
```js
const github = require('@actions/github');
@@ -17,10 +17,7 @@ async function run() {
// https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret
const myToken = core.getInput('myToken');
const octokit = github.getOctokit(myToken)
// You can also pass in additional options as a second parameter to getOctokit
// const octokit = github.getOctokit(myToken, {userAgent: "MyActionVersion1"});
const octokit = new github.GitHub(myToken);
const { data: pullRequest } = await octokit.pulls.get({
owner: 'octokit',
@@ -37,6 +34,8 @@ async function run() {
run();
```
You can pass client options, as specified by [Octokit](https://octokit.github.io/rest.js/), as a second argument to the `GitHub` constructor.
You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API.
```js
@@ -73,25 +72,3 @@ if (github.context.eventName === 'push') {
core.info(`The head commit is: ${pushPayload.head}`)
}
```
## Extending the Octokit instance
`@octokit/core` now supports the [plugin architecture](https://github.com/octokit/core.js#plugins). You can extend the GitHub instance using plugins.
For example, using the `@octokit/plugin-enterprise-server` you can now access enterprise admin apis on GHES instances.
```ts
import { GitHub, getOctokitOptions } from '@actions/github/lib/utils'
import { enterpriseServer220Admin } from '@octokit/plugin-enterprise-server'
const octokit = GitHub.plugin(enterpriseServer220Admin)
// or override some of the default values as well
// const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"})
const myToken = core.getInput('myToken');
const myOctokit = new octokit(getOctokitOptions(token))
// Create a new user
myOctokit.enterpriseAdmin.createUser({
login: "testuser",
email: "testuser@test.com",
});
```

View File

@@ -10,9 +10,6 @@ export declare class Context {
workflow: string;
action: string;
actor: string;
job: string;
runNumber: number;
runId: number;
/**
* Hydrate the context from the environment
*/

View File

@@ -1,6 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Context = void 0;
const fs_1 = require("fs");
const os_1 = require("os");
class Context {
@@ -24,9 +23,6 @@ class Context {
this.workflow = process.env.GITHUB_WORKFLOW;
this.action = process.env.GITHUB_ACTION;
this.actor = process.env.GITHUB_ACTOR;
this.job = process.env.GITHUB_JOB;
this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);
this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);
}
get issue() {
const payload = this.payload;

View File

@@ -1 +1 @@
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;;AAEA,2BAA2C;AAC3C,2BAAsB;AAEtB,MAAa,OAAO;IAgBlB;;OAEG;IACH;QACE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;QACjB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACjC,IAAI,eAAU,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE;gBAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CACvB,iBAAY,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,CAAC,CAChE,CAAA;aACF;iBAAM;gBACL,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;gBAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,kBAAkB,QAAG,EAAE,CAAC,CAAA;aACvE;SACF;QACD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAA2B,CAAA;QACxD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAyB,CAAA;QACrD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAuB,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAsB,CAAA;QAC/C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAA2B,EAAE,EAAE,CAAC,CAAA;QACtE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAuB,EAAE,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,KAAK;QACP,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAE5B,uCACK,IAAI,CAAC,IAAI,KACZ,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,MAAM,IAClE;IACH,CAAC;IAED,IAAI,IAAI;QACN,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACjC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC9D,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAA;SACrB;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAC3B,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK;gBAC1C,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;aACnC,CAAA;SACF;QAED,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAA;IACH,CAAC;CACF;AApED,0BAoEC"}
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;AAEA,2BAA2C;AAC3C,2BAAsB;AAEtB,MAAa,OAAO;IAalB;;OAEG;IACH;QACE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;QACjB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACjC,IAAI,eAAU,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE;gBAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CACvB,iBAAY,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAC,QAAQ,EAAE,MAAM,EAAC,CAAC,CAChE,CAAA;aACF;iBAAM;gBACL,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;gBAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,kBAAkB,QAAG,EAAE,CAAC,CAAA;aACvE;SACF;QACD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAA2B,CAAA;QACxD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAoB,CAAA;QAC3C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAyB,CAAA;QACrD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAuB,CAAA;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAsB,CAAA;IACjD,CAAC;IAED,IAAI,KAAK;QACP,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAE5B,uCACK,IAAI,CAAC,IAAI,KACZ,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,MAAM,IAClE;IACH,CAAC;IAED,IAAI,IAAI;QACN,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACjC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC9D,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAA;SACrB;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;YAC3B,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK;gBAC1C,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI;aACnC,CAAA;SACF;QAED,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAA;IACH,CAAC;CACF;AA9DD,0BA8DC"}

View File

@@ -1,11 +1,27 @@
import { graphql as GraphQL } from '@octokit/graphql/dist-types/types';
import { Octokit } from '@octokit/rest';
import * as Context from './context';
import { GitHub } from './utils';
import { OctokitOptions } from '@octokit/core/dist-types/types';
export declare const context: Context.Context;
/**
* Returns a hydrated octokit ready to use for GitHub Actions
*
* @param token the repo PAT or GITHUB_TOKEN
* @param options other options to set
*/
export declare function getOctokit(token: string, options?: OctokitOptions): InstanceType<typeof GitHub>;
export declare class GitHub extends Octokit {
graphql: GraphQL;
/**
* Sets up the REST client and GraphQL client with auth and proxy support.
* The parameter `token` or `opts.auth` must be supplied. The GraphQL client
* authorization is not setup when `opts.auth` is a function or object.
*
* @param token Auth token
* @param opts Octokit options
*/
constructor(token: string, opts?: Omit<Octokit.Options, 'auth'>);
constructor(opts: Octokit.Options);
/**
* Disambiguates the constructor overload parameters
*/
private static disambiguate;
private static getOctokitOptions;
private static getGraphQL;
private static getAuthString;
private static getProxyAgent;
private static getApiBaseUrl;
private static getGraphQLBaseUrl;
}

View File

@@ -1,36 +1,108 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
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)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
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 });
exports.getOctokit = exports.context = void 0;
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts
const graphql_1 = require("@octokit/graphql");
const rest_1 = require("@octokit/rest");
const Context = __importStar(require("./context"));
const utils_1 = require("./utils");
const httpClient = __importStar(require("@actions/http-client"));
// We need this in order to extend Octokit
rest_1.Octokit.prototype = new rest_1.Octokit();
exports.context = new Context.Context();
/**
* Returns a hydrated octokit ready to use for GitHub Actions
*
* @param token the repo PAT or GITHUB_TOKEN
* @param options other options to set
*/
function getOctokit(token, options) {
return new utils_1.GitHub(utils_1.getOctokitOptions(token, options));
class GitHub extends rest_1.Octokit {
constructor(token, opts) {
super(GitHub.getOctokitOptions(GitHub.disambiguate(token, opts)));
this.graphql = GitHub.getGraphQL(GitHub.disambiguate(token, opts));
}
/**
* Disambiguates the constructor overload parameters
*/
static disambiguate(token, opts) {
return [
typeof token === 'string' ? token : '',
typeof token === 'object' ? token : opts || {}
];
}
static getOctokitOptions(args) {
const token = args[0];
const options = Object.assign({}, args[1]); // Shallow clone - don't mutate the object provided by the caller
// Base URL - GHES or Dotcom
options.baseUrl = options.baseUrl || this.getApiBaseUrl();
// Auth
const auth = GitHub.getAuthString(token, options);
if (auth) {
options.auth = auth;
}
// Proxy
const agent = GitHub.getProxyAgent(options.baseUrl, options);
if (agent) {
// Shallow clone - don't mutate the object provided by the caller
options.request = options.request ? Object.assign({}, options.request) : {};
// Set the agent
options.request.agent = agent;
}
return options;
}
static getGraphQL(args) {
const defaults = {};
defaults.baseUrl = this.getGraphQLBaseUrl();
const token = args[0];
const options = args[1];
// Authorization
const auth = this.getAuthString(token, options);
if (auth) {
defaults.headers = {
authorization: auth
};
}
// Proxy
const agent = GitHub.getProxyAgent(defaults.baseUrl, options);
if (agent) {
defaults.request = { agent };
}
return graphql_1.graphql.defaults(defaults);
}
static getAuthString(token, options) {
// Validate args
if (!token && !options.auth) {
throw new Error('Parameter token or opts.auth is required');
}
else if (token && options.auth) {
throw new Error('Parameters token and opts.auth may not both be specified');
}
return typeof options.auth === 'string' ? options.auth : `token ${token}`;
}
static getProxyAgent(destinationUrl, options) {
var _a;
if (!((_a = options.request) === null || _a === void 0 ? void 0 : _a.agent)) {
if (httpClient.getProxyUrl(destinationUrl)) {
const hc = new httpClient.HttpClient();
return hc.getAgent(destinationUrl);
}
}
return undefined;
}
static getApiBaseUrl() {
return process.env['GITHUB_API_URL'] || 'https://api.github.com';
}
static getGraphQLBaseUrl() {
let url = process.env['GITHUB_GRAPHQL_URL'] || 'https://api.github.com/graphql';
// Shouldn't be a trailing slash, but remove if so
if (url.endsWith('/')) {
url = url.substr(0, url.length - 1);
}
// Remove trailing "/graphql"
if (url.toUpperCase().endsWith('/GRAPHQL')) {
url = url.substr(0, url.length - '/graphql'.length);
}
return url;
}
}
exports.getOctokit = getOctokit;
exports.GitHub = GitHub;
//# sourceMappingURL=github.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAoC;AACpC,mCAAiD;AAKpC,QAAA,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;AAE5C;;;;;GAKG;AACH,SAAgB,UAAU,CACxB,KAAa,EACb,OAAwB;IAExB,OAAO,IAAI,cAAM,CAAC,yBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;AACtD,CAAC;AALD,gCAKC"}
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}

View File

@@ -33,8 +33,4 @@ export interface WebhookPayload {
id: number;
[key: string]: any;
};
comment?: {
id: number;
[key: string]: any;
};
}

View File

@@ -1,6 +0,0 @@
/// <reference types="node" />
import * as http from 'http';
import { OctokitOptions } from '@octokit/core/dist-types/types';
export declare function getAuthString(token: string, options: OctokitOptions): string | undefined;
export declare function getProxyAgent(destinationUrl: string): http.Agent;
export declare function getApiBaseUrl(): string;

View File

@@ -1,43 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
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)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0;
const httpClient = __importStar(require("@actions/http-client"));
function getAuthString(token, options) {
if (!token && !options.auth) {
throw new Error('Parameter token or opts.auth is required');
}
else if (token && options.auth) {
throw new Error('Parameters token and opts.auth may not both be specified');
}
return typeof options.auth === 'string' ? options.auth : `token ${token}`;
}
exports.getAuthString = getAuthString;
function getProxyAgent(destinationUrl) {
const hc = new httpClient.HttpClient();
return hc.getAgent(destinationUrl);
}
exports.getProxyAgent = getProxyAgent;
function getApiBaseUrl() {
return process.env['GITHUB_API_URL'] || 'https://api.github.com';
}
exports.getApiBaseUrl = getApiBaseUrl;
//# sourceMappingURL=utils.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,iEAAkD;AAGlD,SAAgB,aAAa,CAC3B,KAAa,EACb,OAAuB;IAEvB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QAC3B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;KAC5D;SAAM,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;KAC5E;IAED,OAAO,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAA;AAC3E,CAAC;AAXD,sCAWC;AAED,SAAgB,aAAa,CAAC,cAAsB;IAClD,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,CAAA;IACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;AACpC,CAAC;AAHD,sCAGC;AAED,SAAgB,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,wBAAwB,CAAA;AAClE,CAAC;AAFD,sCAEC"}

View File

@@ -1,21 +0,0 @@
import * as Context from './context';
import { Octokit } from '@octokit/core';
import { OctokitOptions } from '@octokit/core/dist-types/types';
export declare const context: Context.Context;
export declare const GitHub: (new (...args: any[]) => {
[x: string]: any;
}) & {
new (...args: any[]): {
[x: string]: any;
};
plugins: any[];
} & typeof Octokit & import("@octokit/core/dist-types/types").Constructor<import("@octokit/plugin-rest-endpoint-methods/dist-types/generated/method-types").RestEndpointMethods & {
paginate: import("@octokit/plugin-paginate-rest").PaginateInterface;
}>;
/**
* Convience function to correctly format Octokit Options to pass into the constructor.
*
* @param token the repo PAT or GITHUB_TOKEN
* @param options other options to set
*/
export declare function getOctokitOptions(token: string, options?: OctokitOptions): OctokitOptions;

View File

@@ -1,54 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
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)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOctokitOptions = exports.GitHub = exports.context = void 0;
const Context = __importStar(require("./context"));
const Utils = __importStar(require("./internal/utils"));
// octokit + plugins
const core_1 = require("@octokit/core");
const plugin_rest_endpoint_methods_1 = require("@octokit/plugin-rest-endpoint-methods");
const plugin_paginate_rest_1 = require("@octokit/plugin-paginate-rest");
exports.context = new Context.Context();
const baseUrl = Utils.getApiBaseUrl();
const defaults = {
baseUrl,
request: {
agent: Utils.getProxyAgent(baseUrl)
}
};
exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults);
/**
* Convience function to correctly format Octokit Options to pass into the constructor.
*
* @param token the repo PAT or GITHUB_TOKEN
* @param options other options to set
*/
function getOctokitOptions(token, options) {
const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller
// Auth
const auth = Utils.getAuthString(token, opts);
if (auth) {
opts.auth = auth;
}
return opts;
}
exports.getOctokitOptions = getOctokitOptions;
//# sourceMappingURL=utils.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAoC;AACpC,wDAAyC;AAEzC,oBAAoB;AACpB,wCAAqC;AAErC,wFAAyE;AACzE,wEAA0D;AAE7C,QAAA,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;AAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,EAAE,CAAA;AACrC,MAAM,QAAQ,GAAG;IACf,OAAO;IACP,OAAO,EAAE;QACP,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;KACpC;CACF,CAAA;AAEY,QAAA,MAAM,GAAG,cAAO,CAAC,MAAM,CAClC,kDAAmB,EACnB,mCAAY,CACb,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAEpB;;;;;GAKG;AACH,SAAgB,iBAAiB,CAC/B,KAAa,EACb,OAAwB;IAExB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA,CAAC,iEAAiE;IAE/G,OAAO;IACP,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;KACjB;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAbD,8CAaC"}

View File

@@ -4,6 +4,7 @@
[![@latest](https://img.shields.io/npm/v/@octokit/plugin-paginate-rest.svg)](https://www.npmjs.com/package/@octokit/plugin-paginate-rest)
[![Build Status](https://github.com/octokit/plugin-paginate-rest.js/workflows/Test/badge.svg)](https://github.com/octokit/plugin-paginate-rest.js/actions?workflow=Test)
[![Greenkeeper](https://badges.greenkeeper.io/octokit/plugin-paginate-rest.js.svg)](https://greenkeeper.io/)
## Usage
@@ -47,11 +48,11 @@ const issues = await octokit.paginate("GET /repos/:owner/:repo/issues", {
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
per_page: 100
});
```
## `octokit.paginate()`
## `octokit.paginate(route, parameters, mapFunction)` or `octokit.paginate(options, mapFunction)`
The `paginateRest` plugin adds a new `octokit.paginate()` method which accepts the same parameters as [`octokit.request`](https://github.com/octokit/request.js#request). Only "List ..." endpoints such as [List issues for a repository](https://developer.github.com/v3/issues/#list-issues-for-a-repository) are supporting pagination. Their [response includes a Link header](https://developer.github.com/v3/issues/#response-1). For other endpoints, `octokit.paginate()` behaves the same as `octokit.request()`.
@@ -66,9 +67,9 @@ const issueTitles = await octokit.paginate(
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
per_page: 100
},
(response) => response.data.map((issue) => issue.title)
response => response.data.map(issue => issue.title)
);
```
@@ -81,10 +82,10 @@ const issues = await octokit.paginate(
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
per_page: 100
},
(response, done) => {
if (response.data.find((issues) => issue.title.includes("something"))) {
if (response.data.find(issues => issue.title.includes("something"))) {
done();
}
return response.data;
@@ -92,52 +93,20 @@ const issues = await octokit.paginate(
);
```
Alternatively you can pass a `request` method as first argument. This is great when using in combination with [`@octokit/plugin-rest-endpoint-methods`](https://github.com/octokit/plugin-rest-endpoint-methods.js/):
```js
const issues = await octokit.paginate(octokit.issues.listForRepo, {
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
});
```
## `octokit.paginate.iterator()`
## `octokit.paginate.iterator(route, parameters)` or `octokit.paginate.iterator(options)`
If your target runtime environments supports async iterators (such as most modern browsers and Node 10+), you can iterate through each response
```js
const parameters = {
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
};
for await (const response of octokit.paginate.iterator(
"GET /repos/:owner/:repo/issues",
parameters
)) {
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100
}
for await (const response of octokit.paginate.iterator("GET /repos/:owner/:repo/issues", parameters)) {
// do whatever you want with each response, break out of the loop, etc.
console.log(response.data.title);
}
```
Alternatively you can pass a `request` method as first argument. This is great when using in combination with [`@octokit/plugin-rest-endpoint-methods`](https://github.com/octokit/plugin-rest-endpoint-methods.js/):
```js
const parameters = {
owner: "octocat",
repo: "hello-world",
since: "2010-10-01",
per_page: 100,
};
for await (const response of octokit.paginate.iterator(
octokit.issues.listForRepo,
parameters
)) {
// do whatever you want with each response, break out of the loop, etc.
console.log(response.data.title);
console.log(response.data.title)
}
```
@@ -145,7 +114,7 @@ for await (const response of octokit.paginate.iterator(
`octokit.paginate()` wraps `octokit.request()`. As long as a `rel="next"` link value is present in the response's `Link` header, it sends another request for that URL, and so on.
Most of GitHub's paginating REST API endpoints return an array, but there are a few exceptions which return an object with a key that includes the items array. For example:
Most of GitHub's paginating REST API endpoints return an array, but there are a few exceptions which return an object with a key that includes the items array.
- [Search repositories](https://developer.github.com/v3/search/#example) (key `items`)
- [List check runs for a specific ref](https://developer.github.com/v3/checks/runs/#response-3) (key: `check_runs`)

View File

@@ -2,27 +2,33 @@
Object.defineProperty(exports, '__esModule', { value: true });
const VERSION = "2.4.0";
const VERSION = "1.1.2";
/**
* Some list response that can be paginated have a different response structure
*
* They have a `total_count` key in the response (search also has `incomplete_results`,
* /installation/repositories also has `repository_selection`), as well as a key with
* the list of the items which name varies from endpoint to endpoint.
* the list of the items which name varies from endpoint to endpoint:
*
* - https://developer.github.com/v3/search/#example (key `items`)
* - https://developer.github.com/v3/checks/runs/#response-3 (key: `check_runs`)
* - https://developer.github.com/v3/checks/suites/#response-1 (key: `check_suites`)
* - https://developer.github.com/v3/apps/installations/#list-repositories (key: `repositories`)
* - https://developer.github.com/v3/apps/installations/#list-installations-for-a-user (key `installations`)
*
* Octokit normalizes these responses so that paginated results are always returned following
* the same structure. One challenge is that if the list response has only one page, no Link
* header is provided, so this header alone is not sufficient to check wether a response is
* paginated or not.
*
* We check if a "total_count" key is present in the response data, but also make sure that
* a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
* otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
* paginated or not. For the exceptions with the namespace, a fallback check for the route
* paths has to be added in order to normalize the response. We cannot check for the total_count
* property because it also exists in the response of Get the combined status for a specific ref.
*/
function normalizePaginatedListResponse(response) {
const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way
const REGEX = [/^\/search\//, /^\/repos\/[^/]+\/[^/]+\/commits\/[^/]+\/(check-runs|check-suites)([^/]|$)/, /^\/installation\/repositories([^/]|$)/, /^\/user\/installations([^/]|$)/, /^\/repos\/[^/]+\/[^/]+\/actions\/secrets([^/]|$)/, /^\/repos\/[^/]+\/[^/]+\/actions\/workflows(\/[^/]+\/runs)?([^/]|$)/, /^\/repos\/[^/]+\/[^/]+\/actions\/runs(\/[^/]+\/(artifacts|jobs))?([^/]|$)/];
function normalizePaginatedListResponse(octokit, url, response) {
const path = url.replace(octokit.request.endpoint.DEFAULTS.baseUrl, "");
const responseNeedsNormalization = REGEX.find(regex => regex.test(path));
if (!responseNeedsNormalization) return; // keep the additional properties intact as there is currently no other way
// to retrieve the same information.
const incompleteResults = response.data.incomplete_results;
@@ -44,12 +50,17 @@ function normalizePaginatedListResponse(response) {
}
response.data.total_count = totalCount;
return response;
Object.defineProperty(response.data, namespaceKey, {
get() {
octokit.log.warn(`[@octokit/paginate-rest] "response.data.${namespaceKey}" is deprecated for "GET ${path}". Get the results directly from "response.data"`);
return Array.from(data);
}
});
}
function iterator(octokit, route, parameters) {
const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);
const requestMethod = typeof route === "function" ? route : octokit.request;
const options = octokit.request.endpoint(route, parameters);
const method = options.method;
const headers = options.headers;
let url = options.url;
@@ -62,14 +73,15 @@ function iterator(octokit, route, parameters) {
});
}
return requestMethod({
return octokit.request({
method,
url,
headers
}).then(normalizePaginatedListResponse).then(response => {
// `response.headers.link` format:
}).then(response => {
normalizePaginatedListResponse(octokit, url, response); // `response.headers.link` format:
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
// sets `url` to undefined if "next" URL is not present or `link` header is not set
url = ((response.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
return {
value: response

File diff suppressed because one or more lines are too long

View File

@@ -8,8 +8,8 @@ import { iterator } from "./iterator";
export function paginateRest(octokit) {
return {
paginate: Object.assign(paginate.bind(null, octokit), {
iterator: iterator.bind(null, octokit),
}),
iterator: iterator.bind(null, octokit)
})
};
}
paginateRest.VERSION = VERSION;

View File

@@ -1,9 +1,6 @@
import { normalizePaginatedListResponse } from "./normalize-paginated-list-response";
export function iterator(octokit, route, parameters) {
const options = typeof route === "function"
? route.endpoint(parameters)
: octokit.request.endpoint(route, parameters);
const requestMethod = typeof route === "function" ? route : octokit.request;
const options = octokit.request.endpoint(route, parameters);
const method = options.method;
const headers = options.headers;
let url = options.url;
@@ -13,16 +10,17 @@ export function iterator(octokit, route, parameters) {
if (!url) {
return Promise.resolve({ done: true });
}
return requestMethod({ method, url, headers })
.then(normalizePaginatedListResponse)
return octokit
.request({ method, url, headers })
.then((response) => {
normalizePaginatedListResponse(octokit, url, response);
// `response.headers.link` format:
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
// sets `url` to undefined if "next" URL is not present or `link` header is not set
url = ((response.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
return { value: response };
});
},
}),
}
})
};
}

View File

@@ -0,0 +1,59 @@
/**
* Some “list” response that can be paginated have a different response structure
*
* They have a `total_count` key in the response (search also has `incomplete_results`,
* /installation/repositories also has `repository_selection`), as well as a key with
* the list of the items which name varies from endpoint to endpoint:
*
* - https://developer.github.com/v3/search/#example (key `items`)
* - https://developer.github.com/v3/checks/runs/#response-3 (key: `check_runs`)
* - https://developer.github.com/v3/checks/suites/#response-1 (key: `check_suites`)
* - https://developer.github.com/v3/apps/installations/#list-repositories (key: `repositories`)
* - https://developer.github.com/v3/apps/installations/#list-installations-for-a-user (key `installations`)
*
* Octokit normalizes these responses so that paginated results are always returned following
* the same structure. One challenge is that if the list response has only one page, no Link
* header is provided, so this header alone is not sufficient to check wether a response is
* paginated or not. For the exceptions with the namespace, a fallback check for the route
* paths has to be added in order to normalize the response. We cannot check for the total_count
* property because it also exists in the response of Get the combined status for a specific ref.
*/
const REGEX = [
/^\/search\//,
/^\/repos\/[^/]+\/[^/]+\/commits\/[^/]+\/(check-runs|check-suites)([^/]|$)/,
/^\/installation\/repositories([^/]|$)/,
/^\/user\/installations([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/secrets([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/workflows(\/[^/]+\/runs)?([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/runs(\/[^/]+\/(artifacts|jobs))?([^/]|$)/
];
export function normalizePaginatedListResponse(octokit, url, response) {
const path = url.replace(octokit.request.endpoint.DEFAULTS.baseUrl, "");
const responseNeedsNormalization = REGEX.find(regex => regex.test(path));
if (!responseNeedsNormalization)
return;
// keep the additional properties intact as there is currently no other way
// to retrieve the same information.
const incompleteResults = response.data.incomplete_results;
const repositorySelection = response.data.repository_selection;
const totalCount = response.data.total_count;
delete response.data.incomplete_results;
delete response.data.repository_selection;
delete response.data.total_count;
const namespaceKey = Object.keys(response.data)[0];
const data = response.data[namespaceKey];
response.data = data;
if (typeof incompleteResults !== "undefined") {
response.data.incomplete_results = incompleteResults;
}
if (typeof repositorySelection !== "undefined") {
response.data.repository_selection = repositorySelection;
}
response.data.total_count = totalCount;
Object.defineProperty(response.data, namespaceKey, {
get() {
octokit.log.warn(`[@octokit/paginate-rest] "response.data.${namespaceKey}" is deprecated for "GET ${path}". Get the results directly from "response.data"`);
return Array.from(data);
}
});
}

View File

@@ -7,7 +7,7 @@ export function paginate(octokit, route, parameters, mapFn) {
return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
}
function gather(octokit, results, iterator, mapFn) {
return iterator.next().then((result) => {
return iterator.next().then(result => {
if (result.done) {
return results;
}

View File

@@ -0,0 +1 @@
export const VERSION = "1.1.2";

View File

@@ -1,6 +1,6 @@
import { Octokit } from "@octokit/core";
import { RequestInterface, OctokitResponse, RequestParameters, Route } from "./types";
export declare function iterator(octokit: Octokit, route: Route | RequestInterface, parameters?: RequestParameters): {
import { OctokitResponse, RequestParameters, Route } from "./types";
export declare function iterator(octokit: Octokit, route: Route, parameters?: RequestParameters): {
[Symbol.asyncIterator]: () => {
next(): Promise<{
done: boolean;

View File

@@ -0,0 +1,23 @@
/**
* Some “list” response that can be paginated have a different response structure
*
* They have a `total_count` key in the response (search also has `incomplete_results`,
* /installation/repositories also has `repository_selection`), as well as a key with
* the list of the items which name varies from endpoint to endpoint:
*
* - https://developer.github.com/v3/search/#example (key `items`)
* - https://developer.github.com/v3/checks/runs/#response-3 (key: `check_runs`)
* - https://developer.github.com/v3/checks/suites/#response-1 (key: `check_suites`)
* - https://developer.github.com/v3/apps/installations/#list-repositories (key: `repositories`)
* - https://developer.github.com/v3/apps/installations/#list-installations-for-a-user (key `installations`)
*
* Octokit normalizes these responses so that paginated results are always returned following
* the same structure. One challenge is that if the list response has only one page, no Link
* header is provided, so this header alone is not sufficient to check wether a response is
* paginated or not. For the exceptions with the namespace, a fallback check for the route
* paths has to be added in order to normalize the response. We cannot check for the total_count
* property because it also exists in the response of Get the combined status for a specific ref.
*/
import { Octokit } from "@octokit/core";
import { OctokitResponse } from "./types";
export declare function normalizePaginatedListResponse(octokit: Octokit, url: string, response: OctokitResponse<any>): void;

View File

@@ -0,0 +1,3 @@
import { Octokit } from "@octokit/core";
import { MapFunction, PaginationResults, RequestParameters, Route } from "./types";
export declare function paginate(octokit: Octokit, route: Route, parameters?: RequestParameters, mapFn?: MapFunction): Promise<PaginationResults<any>>;

View File

@@ -0,0 +1,69 @@
import * as OctokitTypes from "@octokit/types";
export { EndpointOptions } from "@octokit/types";
export { OctokitResponse } from "@octokit/types";
export { RequestParameters } from "@octokit/types";
export { Route } from "@octokit/types";
export interface PaginateInterface {
/**
* Sends a request based on endpoint options
*
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
* @param {function} mapFn Optional method to map each response to a custom array
*/
<T, R>(options: OctokitTypes.EndpointOptions, mapFn: MapFunction<T, R>): Promise<PaginationResults<R>>;
/**
* Sends a request based on endpoint options
*
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<T>(options: OctokitTypes.EndpointOptions): Promise<PaginationResults<T>>;
/**
* Sends a request based on endpoint options
*
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {function} mapFn Optional method to map each response to a custom array
*/
<T, R>(route: OctokitTypes.Route, mapFn: MapFunction<T>): Promise<PaginationResults<R>>;
/**
* Sends a request based on endpoint options
*
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
* @param {function} mapFn Optional method to map each response to a custom array
*/
<T, R>(route: OctokitTypes.Route, parameters: OctokitTypes.RequestParameters, mapFn: MapFunction<T>): Promise<PaginationResults<R>>;
/**
* Sends a request based on endpoint options
*
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {object} parameters URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<T>(route: OctokitTypes.Route, parameters: OctokitTypes.RequestParameters): Promise<PaginationResults<T>>;
/**
* Sends a request based on endpoint options
*
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
*/
<T>(route: OctokitTypes.Route): Promise<PaginationResults<T>>;
iterator: {
/**
* Get an asynchronous iterator for use with `for await()`,
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
* @param {object} endpoint Must set `method` and `url`. Plus URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<T>(EndpointOptions: OctokitTypes.EndpointOptions): AsyncIterableIterator<OctokitTypes.OctokitResponse<PaginationResults<T>>>;
/**
* Get an asynchronous iterator for use with `for await()`,
*
* @see {link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of} for await...of
* @param {string} route Request method + URL. Example: `'GET /orgs/:org'`
* @param {object} [parameters] URL, query or body parameters, as well as `headers`, `mediaType.{format|previews}`, `request`, or `baseUrl`.
*/
<T>(route: OctokitTypes.Route, parameters?: OctokitTypes.RequestParameters): AsyncIterableIterator<OctokitTypes.OctokitResponse<PaginationResults<T>>>;
};
}
export interface MapFunction<T = any, R = any> {
(response: OctokitTypes.OctokitResponse<PaginationResults<T>>, done: () => void): R[];
}
export declare type PaginationResults<T = any> = T[];

View File

@@ -0,0 +1 @@
export declare const VERSION = "1.1.2";

View File

@@ -1,25 +1,39 @@
const VERSION = "2.4.0";
const VERSION = "1.1.2";
/**
* Some list response that can be paginated have a different response structure
*
* They have a `total_count` key in the response (search also has `incomplete_results`,
* /installation/repositories also has `repository_selection`), as well as a key with
* the list of the items which name varies from endpoint to endpoint.
* the list of the items which name varies from endpoint to endpoint:
*
* - https://developer.github.com/v3/search/#example (key `items`)
* - https://developer.github.com/v3/checks/runs/#response-3 (key: `check_runs`)
* - https://developer.github.com/v3/checks/suites/#response-1 (key: `check_suites`)
* - https://developer.github.com/v3/apps/installations/#list-repositories (key: `repositories`)
* - https://developer.github.com/v3/apps/installations/#list-installations-for-a-user (key `installations`)
*
* Octokit normalizes these responses so that paginated results are always returned following
* the same structure. One challenge is that if the list response has only one page, no Link
* header is provided, so this header alone is not sufficient to check wether a response is
* paginated or not.
*
* We check if a "total_count" key is present in the response data, but also make sure that
* a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
* otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
* paginated or not. For the exceptions with the namespace, a fallback check for the route
* paths has to be added in order to normalize the response. We cannot check for the total_count
* property because it also exists in the response of Get the combined status for a specific ref.
*/
function normalizePaginatedListResponse(response) {
const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
const REGEX = [
/^\/search\//,
/^\/repos\/[^/]+\/[^/]+\/commits\/[^/]+\/(check-runs|check-suites)([^/]|$)/,
/^\/installation\/repositories([^/]|$)/,
/^\/user\/installations([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/secrets([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/workflows(\/[^/]+\/runs)?([^/]|$)/,
/^\/repos\/[^/]+\/[^/]+\/actions\/runs(\/[^/]+\/(artifacts|jobs))?([^/]|$)/
];
function normalizePaginatedListResponse(octokit, url, response) {
const path = url.replace(octokit.request.endpoint.DEFAULTS.baseUrl, "");
const responseNeedsNormalization = REGEX.find(regex => regex.test(path));
if (!responseNeedsNormalization)
return response;
return;
// keep the additional properties intact as there is currently no other way
// to retrieve the same information.
const incompleteResults = response.data.incomplete_results;
@@ -38,14 +52,16 @@ function normalizePaginatedListResponse(response) {
response.data.repository_selection = repositorySelection;
}
response.data.total_count = totalCount;
return response;
Object.defineProperty(response.data, namespaceKey, {
get() {
octokit.log.warn(`[@octokit/paginate-rest] "response.data.${namespaceKey}" is deprecated for "GET ${path}". Get the results directly from "response.data"`);
return Array.from(data);
}
});
}
function iterator(octokit, route, parameters) {
const options = typeof route === "function"
? route.endpoint(parameters)
: octokit.request.endpoint(route, parameters);
const requestMethod = typeof route === "function" ? route : octokit.request;
const options = octokit.request.endpoint(route, parameters);
const method = options.method;
const headers = options.headers;
let url = options.url;
@@ -55,17 +71,18 @@ function iterator(octokit, route, parameters) {
if (!url) {
return Promise.resolve({ done: true });
}
return requestMethod({ method, url, headers })
.then(normalizePaginatedListResponse)
return octokit
.request({ method, url, headers })
.then((response) => {
normalizePaginatedListResponse(octokit, url, response);
// `response.headers.link` format:
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
// sets `url` to undefined if "next" URL is not present or `link` header is not set
url = ((response.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
return { value: response };
});
},
}),
}
})
};
}
@@ -77,7 +94,7 @@ function paginate(octokit, route, parameters, mapFn) {
return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
}
function gather(octokit, results, iterator, mapFn) {
return iterator.next().then((result) => {
return iterator.next().then(result => {
if (result.done) {
return results;
}
@@ -100,8 +117,8 @@ function gather(octokit, results, iterator, mapFn) {
function paginateRest(octokit) {
return {
paginate: Object.assign(paginate.bind(null, octokit), {
iterator: iterator.bind(null, octokit),
}),
iterator: iterator.bind(null, octokit)
})
};
}
paginateRest.VERSION = VERSION;

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"name": "@octokit/plugin-paginate-rest",
"description": "Octokit plugin to paginate REST API endpoint responses",
"version": "2.4.0",
"version": "1.1.2",
"license": "MIT",
"files": [
"dist-*/",
@@ -17,29 +17,24 @@
],
"repository": "https://github.com/octokit/plugin-paginate-rest.js",
"dependencies": {
"@octokit/types": "^5.5.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
"@octokit/types": "^2.0.1"
},
"devDependencies": {
"@octokit/core": "^3.0.0",
"@octokit/plugin-rest-endpoint-methods": "^4.0.0",
"@octokit/core": "^2.0.0",
"@pika/pack": "^0.5.0",
"@pika/plugin-build-node": "^0.9.0",
"@pika/plugin-build-web": "^0.9.0",
"@pika/plugin-ts-standard-pkg": "^0.9.0",
"@pika/plugin-build-node": "^0.8.1",
"@pika/plugin-build-web": "^0.8.1",
"@pika/plugin-ts-standard-pkg": "^0.8.1",
"@types/fetch-mock": "^7.3.1",
"@types/jest": "^26.0.0",
"@types/node": "^14.0.4",
"fetch-mock": "^9.0.0",
"jest": "^26.0.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.4",
"@types/jest": "^24.0.18",
"@types/node": "^13.1.0",
"fetch-mock": "^8.0.0",
"jest": "^24.9.0",
"prettier": "^1.18.2",
"semantic-release": "^17.0.0",
"semantic-release-plugin-update-version-in-files": "^1.0.0",
"ts-jest": "^26.0.0",
"typescript": "^4.0.2"
"ts-jest": "^24.1.0",
"typescript": "^3.7.2"
},
"publishConfig": {
"access": "public"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,38 @@
import { Deprecation } from "deprecation";
import endpointsByScope from "./generated/endpoints";
import { VERSION } from "./version";
import { registerEndpoints } from "./register-endpoints";
/**
* This plugin is a 1:1 copy of internal @octokit/rest plugins. The primary
* goal is to rebuild @octokit/rest on top of @octokit/core. Once that is
* done, we will remove the registerEndpoints methods and return the methods
* directly as with the other plugins. At that point we will also remove the
* legacy workarounds and deprecations.
*
* See the plan at
* https://github.com/octokit/plugin-rest-endpoint-methods.js/pull/1
*/
export function restEndpointMethods(octokit) {
// @ts-ignore
octokit.registerEndpoints = registerEndpoints.bind(null, octokit);
registerEndpoints(octokit, endpointsByScope);
// Aliasing scopes for backward compatibility
// See https://github.com/octokit/rest.js/pull/1134
[
["gitdata", "git"],
["authorization", "oauthAuthorizations"],
["pullRequests", "pulls"]
].forEach(([deprecatedScope, scope]) => {
Object.defineProperty(octokit, deprecatedScope, {
get() {
octokit.log.warn(
// @ts-ignore
new Deprecation(`[@octokit/plugin-rest-endpoint-methods] "octokit.${deprecatedScope}.*" methods are deprecated, use "octokit.${scope}.*" instead`));
// @ts-ignore
return octokit[scope];
}
});
});
return {};
}
restEndpointMethods.VERSION = VERSION;

View File

@@ -0,0 +1,60 @@
import { Deprecation } from "deprecation";
export function registerEndpoints(octokit, routes) {
Object.keys(routes).forEach(namespaceName => {
if (!octokit[namespaceName]) {
octokit[namespaceName] = {};
}
Object.keys(routes[namespaceName]).forEach(apiName => {
const apiOptions = routes[namespaceName][apiName];
const endpointDefaults = ["method", "url", "headers"].reduce((map, key) => {
if (typeof apiOptions[key] !== "undefined") {
map[key] = apiOptions[key];
}
return map;
}, {});
endpointDefaults.request = {
validate: apiOptions.params
};
let request = octokit.request.defaults(endpointDefaults);
// patch request & endpoint methods to support deprecated parameters.
// Not the most elegant solution, but we dont want to move deprecation
// logic into octokit/endpoint.js as its out of scope
const hasDeprecatedParam = Object.keys(apiOptions.params || {}).find(key => apiOptions.params[key].deprecated);
if (hasDeprecatedParam) {
const patch = patchForDeprecation.bind(null, octokit, apiOptions);
request = patch(octokit.request.defaults(endpointDefaults), `.${namespaceName}.${apiName}()`);
request.endpoint = patch(request.endpoint, `.${namespaceName}.${apiName}.endpoint()`);
request.endpoint.merge = patch(request.endpoint.merge, `.${namespaceName}.${apiName}.endpoint.merge()`);
}
if (apiOptions.deprecated) {
octokit[namespaceName][apiName] = Object.assign(function deprecatedEndpointMethod() {
octokit.log.warn(new Deprecation(`[@octokit/rest] ${apiOptions.deprecated}`));
octokit[namespaceName][apiName] = request;
return request.apply(null, arguments);
}, request);
return;
}
octokit[namespaceName][apiName] = request;
});
});
}
function patchForDeprecation(octokit, apiOptions, method, methodName) {
const patchedMethod = (options) => {
options = Object.assign({}, options);
Object.keys(options).forEach(key => {
if (apiOptions.params[key] && apiOptions.params[key].deprecated) {
const aliasKey = apiOptions.params[key].alias;
octokit.log.warn(new Deprecation(`[@octokit/rest] "${key}" parameter is deprecated for "${methodName}". Use "${aliasKey}" instead`));
if (!(aliasKey in options)) {
options[aliasKey] = options[key];
}
delete options[key];
}
});
return method(options);
};
Object.keys(method).forEach(key => {
patchedMethod[key] = method[key];
});
return patchedMethod;
}

View File

@@ -1,5 +1,4 @@
import { Octokit } from "@octokit/core";
export { RestEndpointMethodTypes } from "./generated/parameters-and-response-types";
import { Api } from "./types";
/**
* This plugin is a 1:1 copy of internal @octokit/rest plugins. The primary

View File

@@ -0,0 +1 @@
export declare function registerEndpoints(octokit: any, routes: any): void;

View File

@@ -0,0 +1,4 @@
import { RestEndpointMethods } from "./generated/rest-endpoint-methods-types";
export declare type Api = {
registerEndpoints: (endpoints: any) => void;
} & RestEndpointMethods;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"name": "@octokit/plugin-rest-endpoint-methods",
"description": "Octokit plugin adding one method for all of api.github.com REST API endpoints",
"version": "4.2.0",
"version": "2.4.0",
"license": "MIT",
"files": [
"dist-*/",
@@ -17,35 +17,34 @@
],
"repository": "https://github.com/octokit/plugin-rest-endpoint-methods.js",
"dependencies": {
"@octokit/types": "^5.5.0",
"@octokit/types": "^2.0.1",
"deprecation": "^2.3.1"
},
"devDependencies": {
"@gimenete/type-writer": "^0.1.5",
"@octokit/core": "^3.0.0",
"@gimenete/type-writer": "^0.1.4",
"@octokit/core": "^2.1.2",
"@octokit/graphql": "^4.3.1",
"@pika/pack": "^0.5.0",
"@pika/plugin-build-node": "^0.9.0",
"@pika/plugin-build-web": "^0.9.0",
"@pika/plugin-ts-standard-pkg": "^0.9.0",
"@pika/plugin-build-node": "^0.7.1",
"@pika/plugin-build-web": "^0.7.1",
"@pika/plugin-ts-standard-pkg": "^0.7.1",
"@types/fetch-mock": "^7.3.1",
"@types/jest": "^26.0.0",
"@types/node": "^14.0.4",
"fetch-mock": "^9.0.0",
"fs-extra": "^9.0.0",
"jest": "^26.1.0",
"@types/jest": "^25.1.0",
"@types/node": "^13.1.0",
"fetch-mock": "^8.0.0",
"jest": "^24.9.0",
"lodash.camelcase": "^4.3.0",
"lodash.set": "^4.3.2",
"lodash.upperfirst": "^4.3.1",
"mustache": "^4.0.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.1",
"prettier": "^1.19.1",
"semantic-release": "^17.0.0",
"semantic-release-plugin-update-version-in-files": "^1.0.0",
"sort-keys": "^4.0.0",
"string-to-jsdoc-comment": "^1.0.0",
"ts-jest": "^26.1.3",
"typescript": "^4.0.2"
"ts-jest": "^25.1.0",
"typescript": "^3.7.2"
},
"publishConfig": {
"access": "public"

View File

@@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2012 Cloud9 IDE, Inc. (Mike de Boer)
Copyright (c) 2017-2018 Octokit contributors
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.

View File

@@ -0,0 +1,46 @@
# rest.js
> GitHub REST API client for JavaScript
[![@latest](https://img.shields.io/npm/v/@octokit/rest.svg)](https://www.npmjs.com/package/@octokit/rest)
![Build Status](https://github.com/octokit/rest.js/workflows/Test/badge.svg)
[![Greenkeeper](https://badges.greenkeeper.io/octokit/rest.js.svg)](https://greenkeeper.io/)
## Installation
```shell
npm install @octokit/rest
```
## Usage
```js
const { Octokit } = require("@octokit/rest");
const octokit = new Octokit();
// Compare: https://developer.github.com/v3/repos/#list-organization-repositories
octokit.repos
.listForOrg({
org: "octokit",
type: "public"
})
.then(({ data }) => {
// handle data
});
```
See https://octokit.github.io/rest.js/ for full documentation.
## Contributing
We would love you to contribute to `@octokit/rest`, pull requests are very welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
## Credits
`@octokit/rest` was originally created as [`node-github`](https://www.npmjs.com/package/github) in 2012 by Mike de Boer from Cloud9 IDE, Inc.
It was adopted and renamed by GitHub in 2017
## LICENSE
[MIT](LICENSE)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
const { requestLog } = require("@octokit/plugin-request-log");
const {
restEndpointMethods
} = require("@octokit/plugin-rest-endpoint-methods");
const Core = require("./lib/core");
const CORE_PLUGINS = [
require("./plugins/authentication"),
require("./plugins/authentication-deprecated"), // deprecated: remove in v17
requestLog,
require("./plugins/pagination"),
restEndpointMethods,
require("./plugins/validate"),
require("octokit-pagination-methods") // deprecated: remove in v17
];
const OctokitRest = Core.plugin(CORE_PLUGINS);
function DeprecatedOctokit(options) {
const warn =
options && options.log && options.log.warn
? options.log.warn
: console.warn;
warn(
'[@octokit/rest] `const Octokit = require("@octokit/rest")` is deprecated. Use `const { Octokit } = require("@octokit/rest")` instead'
);
return new OctokitRest(options);
}
const Octokit = Object.assign(DeprecatedOctokit, {
Octokit: OctokitRest
});
Object.keys(OctokitRest).forEach(key => {
/* istanbul ignore else */
if (OctokitRest.hasOwnProperty(key)) {
Octokit[key] = OctokitRest[key];
}
});
module.exports = Octokit;

View File

@@ -0,0 +1,29 @@
module.exports = Octokit;
const { request } = require("@octokit/request");
const Hook = require("before-after-hook");
const parseClientOptions = require("./parse-client-options");
function Octokit(plugins, options) {
options = options || {};
const hook = new Hook.Collection();
const log = Object.assign(
{
debug: () => {},
info: () => {},
warn: console.warn,
error: console.error
},
options && options.log
);
const api = {
hook,
log,
request: request.defaults(parseClientOptions(options, log, hook))
};
plugins.forEach(pluginFunction => pluginFunction(api, options));
return api;
}

View File

@@ -0,0 +1,3 @@
const factory = require("./factory");
module.exports = factory();

View File

@@ -0,0 +1,10 @@
module.exports = factory;
const Octokit = require("./constructor");
const registerPlugin = require("./register-plugin");
function factory(plugins) {
const Api = Octokit.bind(null, plugins || []);
Api.plugin = registerPlugin.bind(null, plugins || []);
return Api;
}

View File

@@ -0,0 +1,89 @@
module.exports = parseOptions;
const { Deprecation } = require("deprecation");
const { getUserAgent } = require("universal-user-agent");
const once = require("once");
const pkg = require("../package.json");
const deprecateOptionsTimeout = once((log, deprecation) =>
log.warn(deprecation)
);
const deprecateOptionsAgent = once((log, deprecation) => log.warn(deprecation));
const deprecateOptionsHeaders = once((log, deprecation) =>
log.warn(deprecation)
);
function parseOptions(options, log, hook) {
if (options.headers) {
options.headers = Object.keys(options.headers).reduce((newObj, key) => {
newObj[key.toLowerCase()] = options.headers[key];
return newObj;
}, {});
}
const clientDefaults = {
headers: options.headers || {},
request: options.request || {},
mediaType: {
previews: [],
format: ""
}
};
if (options.baseUrl) {
clientDefaults.baseUrl = options.baseUrl;
}
if (options.userAgent) {
clientDefaults.headers["user-agent"] = options.userAgent;
}
if (options.previews) {
clientDefaults.mediaType.previews = options.previews;
}
if (options.timeZone) {
clientDefaults.headers["time-zone"] = options.timeZone;
}
if (options.timeout) {
deprecateOptionsTimeout(
log,
new Deprecation(
"[@octokit/rest] new Octokit({timeout}) is deprecated. Use {request: {timeout}} instead. See https://github.com/octokit/request.js#request"
)
);
clientDefaults.request.timeout = options.timeout;
}
if (options.agent) {
deprecateOptionsAgent(
log,
new Deprecation(
"[@octokit/rest] new Octokit({agent}) is deprecated. Use {request: {agent}} instead. See https://github.com/octokit/request.js#request"
)
);
clientDefaults.request.agent = options.agent;
}
if (options.headers) {
deprecateOptionsHeaders(
log,
new Deprecation(
"[@octokit/rest] new Octokit({headers}) is deprecated. Use {userAgent, previews} instead. See https://github.com/octokit/request.js#request"
)
);
}
const userAgentOption = clientDefaults.headers["user-agent"];
const defaultUserAgent = `octokit.js/${pkg.version} ${getUserAgent()}`;
clientDefaults.headers["user-agent"] = [userAgentOption, defaultUserAgent]
.filter(Boolean)
.join(" ");
clientDefaults.request.hook = hook.bind(null, "request");
return clientDefaults;
}

View File

@@ -0,0 +1,9 @@
module.exports = registerPlugin;
const factory = require("./factory");
function registerPlugin(plugins, pluginFunction) {
return factory(
plugins.includes(pluginFunction) ? plugins : plugins.concat(pluginFunction)
);
}

View File

@@ -0,0 +1,140 @@
{
"name": "@octokit/rest",
"version": "16.43.2",
"publishConfig": {
"access": "public"
},
"description": "GitHub REST API client for Node.js",
"keywords": [
"octokit",
"github",
"rest",
"api-client"
],
"author": "Gregor Martynus (https://github.com/gr2m)",
"contributors": [
{
"name": "Mike de Boer",
"email": "info@mikedeboer.nl"
},
{
"name": "Fabian Jakobs",
"email": "fabian@c9.io"
},
{
"name": "Joe Gallo",
"email": "joe@brassafrax.com"
},
{
"name": "Gregor Martynus",
"url": "https://github.com/gr2m"
}
],
"repository": "https://github.com/octokit/rest.js",
"dependencies": {
"@octokit/auth-token": "^2.4.0",
"@octokit/plugin-paginate-rest": "^1.1.1",
"@octokit/plugin-request-log": "^1.0.0",
"@octokit/plugin-rest-endpoint-methods": "2.4.0",
"@octokit/request": "^5.2.0",
"@octokit/request-error": "^1.0.2",
"atob-lite": "^2.0.0",
"before-after-hook": "^2.0.0",
"btoa-lite": "^1.0.0",
"deprecation": "^2.0.0",
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"lodash.uniq": "^4.5.0",
"octokit-pagination-methods": "^1.1.0",
"once": "^1.4.0",
"universal-user-agent": "^4.0.0"
},
"devDependencies": {
"@gimenete/type-writer": "^0.1.3",
"@octokit/auth": "^1.1.1",
"@octokit/fixtures-server": "^5.0.6",
"@octokit/graphql": "^4.2.0",
"@types/node": "^13.1.0",
"bundlesize": "^0.18.0",
"chai": "^4.1.2",
"compression-webpack-plugin": "^3.1.0",
"cypress": "^4.0.0",
"glob": "^7.1.2",
"http-proxy-agent": "^4.0.0",
"lodash.camelcase": "^4.3.0",
"lodash.merge": "^4.6.1",
"lodash.upperfirst": "^4.3.1",
"lolex": "^6.0.0",
"mkdirp": "^1.0.0",
"mocha": "^7.0.1",
"mustache": "^4.0.0",
"nock": "^11.3.3",
"npm-run-all": "^4.1.2",
"nyc": "^15.0.0",
"prettier": "^1.14.2",
"proxy": "^1.0.0",
"semantic-release": "^17.0.0",
"sinon": "^8.0.0",
"sinon-chai": "^3.0.0",
"sort-keys": "^4.0.0",
"string-to-arraybuffer": "^1.0.0",
"string-to-jsdoc-comment": "^1.0.0",
"typescript": "^3.3.1",
"webpack": "^4.0.0",
"webpack-bundle-analyzer": "^3.0.0",
"webpack-cli": "^3.0.0"
},
"types": "index.d.ts",
"scripts": {
"coverage": "nyc report --reporter=html && open coverage/index.html",
"lint": "prettier --check '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json",
"lint:fix": "prettier --write '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json",
"pretest": "npm run -s lint",
"test": "nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"",
"test:browser": "cypress run --browser chrome",
"build": "npm-run-all build:*",
"build:ts": "npm run -s update-endpoints:typescript",
"prebuild:browser": "mkdirp dist/",
"build:browser": "npm-run-all build:browser:*",
"build:browser:development": "webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json",
"build:browser:production": "webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map",
"generate-bundle-report": "webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html",
"update-endpoints": "npm-run-all update-endpoints:*",
"update-endpoints:fetch-json": "node scripts/update-endpoints/fetch-json",
"update-endpoints:typescript": "node scripts/update-endpoints/typescript",
"prevalidate:ts": "npm run -s build:ts",
"validate:ts": "tsc --target es6 --noImplicitAny index.d.ts",
"postvalidate:ts": "tsc --noEmit --target es6 test/typescript-validate.ts",
"start-fixtures-server": "octokit-fixtures-server"
},
"license": "MIT",
"files": [
"index.js",
"index.d.ts",
"lib",
"plugins"
],
"nyc": {
"ignore": [
"test"
]
},
"release": {
"publish": [
"@semantic-release/npm",
{
"path": "@semantic-release/github",
"assets": [
"dist/*",
"!dist/*.map.gz"
]
}
]
},
"bundlesize": [
{
"path": "./dist/octokit-rest.min.js.gz",
"maxSize": "33 kB"
}
]
}

View File

@@ -0,0 +1,52 @@
module.exports = authenticate;
const { Deprecation } = require("deprecation");
const once = require("once");
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation));
function authenticate(state, options) {
deprecateAuthenticate(
state.octokit.log,
new Deprecation(
'[@octokit/rest] octokit.authenticate() is deprecated. Use "auth" constructor option instead.'
)
);
if (!options) {
state.auth = false;
return;
}
switch (options.type) {
case "basic":
if (!options.username || !options.password) {
throw new Error(
"Basic authentication requires both a username and password to be set"
);
}
break;
case "oauth":
if (!options.token && !(options.key && options.secret)) {
throw new Error(
"OAuth2 authentication requires a token or key & secret to be set"
);
}
break;
case "token":
case "app":
if (!options.token) {
throw new Error("Token authentication requires a token to be set");
}
break;
default:
throw new Error(
"Invalid authentication type, must be 'basic', 'oauth', 'token' or 'app'"
);
}
state.auth = options;
}

View File

@@ -0,0 +1,43 @@
module.exports = authenticationBeforeRequest;
const btoa = require("btoa-lite");
const uniq = require("lodash.uniq");
function authenticationBeforeRequest(state, options) {
if (!state.auth.type) {
return;
}
if (state.auth.type === "basic") {
const hash = btoa(`${state.auth.username}:${state.auth.password}`);
options.headers.authorization = `Basic ${hash}`;
return;
}
if (state.auth.type === "token") {
options.headers.authorization = `token ${state.auth.token}`;
return;
}
if (state.auth.type === "app") {
options.headers.authorization = `Bearer ${state.auth.token}`;
const acceptHeaders = options.headers.accept
.split(",")
.concat("application/vnd.github.machine-man-preview+json");
options.headers.accept = uniq(acceptHeaders)
.filter(Boolean)
.join(",");
return;
}
options.url += options.url.indexOf("?") === -1 ? "?" : "&";
if (state.auth.token) {
options.url += `access_token=${encodeURIComponent(state.auth.token)}`;
return;
}
const key = encodeURIComponent(state.auth.key);
const secret = encodeURIComponent(state.auth.secret);
options.url += `client_id=${key}&client_secret=${secret}`;
}

View File

@@ -0,0 +1,31 @@
module.exports = authenticationPlugin;
const { Deprecation } = require("deprecation");
const once = require("once");
const deprecateAuthenticate = once((log, deprecation) => log.warn(deprecation));
const authenticate = require("./authenticate");
const beforeRequest = require("./before-request");
const requestError = require("./request-error");
function authenticationPlugin(octokit, options) {
if (options.auth) {
octokit.authenticate = () => {
deprecateAuthenticate(
octokit.log,
new Deprecation(
'[@octokit/rest] octokit.authenticate() is deprecated and has no effect when "auth" option is set on Octokit constructor'
)
);
};
return;
}
const state = {
octokit,
auth: false
};
octokit.authenticate = authenticate.bind(null, state);
octokit.hook.before("request", beforeRequest.bind(null, state));
octokit.hook.error("request", requestError.bind(null, state));
}

View File

@@ -0,0 +1,55 @@
module.exports = authenticationRequestError;
const { RequestError } = require("@octokit/request-error");
function authenticationRequestError(state, error, options) {
/* istanbul ignore next */
if (!error.headers) throw error;
const otpRequired = /required/.test(error.headers["x-github-otp"] || "");
// handle "2FA required" error only
if (error.status !== 401 || !otpRequired) {
throw error;
}
if (
error.status === 401 &&
otpRequired &&
error.request &&
error.request.headers["x-github-otp"]
) {
throw new RequestError(
"Invalid one-time password for two-factor authentication",
401,
{
headers: error.headers,
request: options
}
);
}
if (typeof state.auth.on2fa !== "function") {
throw new RequestError(
"2FA required, but options.on2fa is not a function. See https://github.com/octokit/rest.js#authentication",
401,
{
headers: error.headers,
request: options
}
);
}
return Promise.resolve()
.then(() => {
return state.auth.on2fa();
})
.then(oneTimePassword => {
const newOptions = Object.assign(options, {
headers: Object.assign(
{ "x-github-otp": oneTimePassword },
options.headers
)
});
return state.octokit.request(newOptions);
});
}

View File

@@ -0,0 +1,53 @@
module.exports = authenticationBeforeRequest;
const btoa = require("btoa-lite");
const withAuthorizationPrefix = require("./with-authorization-prefix");
function authenticationBeforeRequest(state, options) {
if (typeof state.auth === "string") {
options.headers.authorization = withAuthorizationPrefix(state.auth);
return;
}
if (state.auth.username) {
const hash = btoa(`${state.auth.username}:${state.auth.password}`);
options.headers.authorization = `Basic ${hash}`;
if (state.otp) {
options.headers["x-github-otp"] = state.otp;
}
return;
}
if (state.auth.clientId) {
// There is a special case for OAuth applications, when `clientId` and `clientSecret` is passed as
// Basic Authorization instead of query parameters. The only routes where that applies share the same
// URL though: `/applications/:client_id/tokens/:access_token`.
//
// 1. [Check an authorization](https://developer.github.com/v3/oauth_authorizations/#check-an-authorization)
// 2. [Reset an authorization](https://developer.github.com/v3/oauth_authorizations/#reset-an-authorization)
// 3. [Revoke an authorization for an application](https://developer.github.com/v3/oauth_authorizations/#revoke-an-authorization-for-an-application)
//
// We identify by checking the URL. It must merge both "/applications/:client_id/tokens/:access_token"
// as well as "/applications/123/tokens/token456"
if (/\/applications\/:?[\w_]+\/tokens\/:?[\w_]+($|\?)/.test(options.url)) {
const hash = btoa(`${state.auth.clientId}:${state.auth.clientSecret}`);
options.headers.authorization = `Basic ${hash}`;
return;
}
options.url += options.url.indexOf("?") === -1 ? "?" : "&";
options.url += `client_id=${state.auth.clientId}&client_secret=${state.auth.clientSecret}`;
return;
}
return Promise.resolve()
.then(() => {
return state.auth();
})
.then(authorization => {
options.headers.authorization = withAuthorizationPrefix(authorization);
});
}

View File

@@ -0,0 +1,76 @@
module.exports = authenticationPlugin;
const { createTokenAuth } = require("@octokit/auth-token");
const { Deprecation } = require("deprecation");
const once = require("once");
const beforeRequest = require("./before-request");
const requestError = require("./request-error");
const validate = require("./validate");
const withAuthorizationPrefix = require("./with-authorization-prefix");
const deprecateAuthBasic = once((log, deprecation) => log.warn(deprecation));
const deprecateAuthObject = once((log, deprecation) => log.warn(deprecation));
function authenticationPlugin(octokit, options) {
// If `options.authStrategy` is set then use it and pass in `options.auth`
if (options.authStrategy) {
const auth = options.authStrategy(options.auth);
octokit.hook.wrap("request", auth.hook);
octokit.auth = auth;
return;
}
// If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance
// is unauthenticated. The `octokit.auth()` method is a no-op and no request hook is registred.
if (!options.auth) {
octokit.auth = () =>
Promise.resolve({
type: "unauthenticated"
});
return;
}
const isBasicAuthString =
typeof options.auth === "string" &&
/^basic/.test(withAuthorizationPrefix(options.auth));
// If only `options.auth` is set to a string, use the default token authentication strategy.
if (typeof options.auth === "string" && !isBasicAuthString) {
const auth = createTokenAuth(options.auth);
octokit.hook.wrap("request", auth.hook);
octokit.auth = auth;
return;
}
// Otherwise log a deprecation message
const [deprecationMethod, deprecationMessapge] = isBasicAuthString
? [
deprecateAuthBasic,
'Setting the "new Octokit({ auth })" option to a Basic Auth string is deprecated. Use https://github.com/octokit/auth-basic.js instead. See (https://octokit.github.io/rest.js/#authentication)'
]
: [
deprecateAuthObject,
'Setting the "new Octokit({ auth })" option to an object without also setting the "authStrategy" option is deprecated and will be removed in v17. See (https://octokit.github.io/rest.js/#authentication)'
];
deprecationMethod(
octokit.log,
new Deprecation("[@octokit/rest] " + deprecationMessapge)
);
octokit.auth = () =>
Promise.resolve({
type: "deprecated",
message: deprecationMessapge
});
validate(options.auth);
const state = {
octokit,
auth: options.auth
};
octokit.hook.before("request", beforeRequest.bind(null, state));
octokit.hook.error("request", requestError.bind(null, state));
}

View File

@@ -0,0 +1,61 @@
module.exports = authenticationRequestError;
const { RequestError } = require("@octokit/request-error");
function authenticationRequestError(state, error, options) {
if (!error.headers) throw error;
const otpRequired = /required/.test(error.headers["x-github-otp"] || "");
// handle "2FA required" error only
if (error.status !== 401 || !otpRequired) {
throw error;
}
if (
error.status === 401 &&
otpRequired &&
error.request &&
error.request.headers["x-github-otp"]
) {
if (state.otp) {
delete state.otp; // no longer valid, request again
} else {
throw new RequestError(
"Invalid one-time password for two-factor authentication",
401,
{
headers: error.headers,
request: options
}
);
}
}
if (typeof state.auth.on2fa !== "function") {
throw new RequestError(
"2FA required, but options.on2fa is not a function. See https://github.com/octokit/rest.js#authentication",
401,
{
headers: error.headers,
request: options
}
);
}
return Promise.resolve()
.then(() => {
return state.auth.on2fa();
})
.then(oneTimePassword => {
const newOptions = Object.assign(options, {
headers: Object.assign(options.headers, {
"x-github-otp": oneTimePassword
})
});
return state.octokit.request(newOptions).then(response => {
// If OTP still valid, then persist it for following requests
state.otp = oneTimePassword;
return response;
});
});
}

View File

@@ -0,0 +1,21 @@
module.exports = validateAuth;
function validateAuth(auth) {
if (typeof auth === "string") {
return;
}
if (typeof auth === "function") {
return;
}
if (auth.username && auth.password) {
return;
}
if (auth.clientId && auth.clientSecret) {
return;
}
throw new Error(`Invalid "auth" option: ${JSON.stringify(auth)}`);
}

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