mirror of
https://github.com/github/codeql-action.git
synced 2025-12-07 00:08:06 +08:00
Compare commits
2 Commits
v1.0.5
...
daverlo/te
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
068ef74bd6 | ||
|
|
afde6a46b1 |
@@ -18,20 +18,15 @@
|
||||
"import/no-amd": "error",
|
||||
"import/no-commonjs": "error",
|
||||
"import/no-dynamic-require": "error",
|
||||
"import/no-extraneous-dependencies": ["error"],
|
||||
"import/no-extraneous-dependencies": ["error", {"devDependencies": false}],
|
||||
"import/no-namespace": "off",
|
||||
"import/no-unresolved": "error",
|
||||
"import/no-webpack-loader-syntax": "error",
|
||||
"import/order": ["error", {
|
||||
"alphabetize": {"order": "asc"},
|
||||
"newlines-between": "always"
|
||||
}],
|
||||
"no-async-foreach/no-async-foreach": "error",
|
||||
"no-console": "off",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"@typescript-eslint/no-shadow": ["error"],
|
||||
"one-var": ["error", "never"]
|
||||
"one-var": ["error", "never"],
|
||||
"sort-imports": ["error", { "allowSeparatedGroups": true }]
|
||||
},
|
||||
"overrides": [{
|
||||
// "temporarily downgraded during transition to eslint
|
||||
@@ -44,11 +39,20 @@
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/prefer-regexp-exec": "off",
|
||||
"@typescript-eslint/require-await": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"func-style": "off"
|
||||
"eslint-comments/no-use": "off",
|
||||
"func-style": "off",
|
||||
"github/no-then": "off",
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"no-shadow": "off",
|
||||
"no-sparse-arrays": "off",
|
||||
"no-throw-literal": "off",
|
||||
"no-useless-escape": "off",
|
||||
"sort-imports": "off"
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
7
.gitattributes
vendored
7
.gitattributes
vendored
@@ -1,8 +1 @@
|
||||
lib/*.js linguist-generated=true
|
||||
|
||||
# Reduce incidence of needless merge conflicts on CHANGELOG.md
|
||||
# The man page at
|
||||
# https://mirrors.edge.kernel.org/pub/software/scm/git/docs/gitattributes.html
|
||||
# suggests that this might interleave lines arbitrarily, but empirically
|
||||
# it keeps added chunks contiguous
|
||||
CHANGELOG.md merge=union
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Contact GitHub Support
|
||||
url: https://support.github.com/request
|
||||
about: Contact Support
|
||||
url: https://support.github.com/contact?subject=Code+Scanning+Beta+Support&tags=code-scanning-support
|
||||
about: Contact Support about code scanning
|
||||
|
||||
3
.github/pull_request_template.md
vendored
3
.github/pull_request_template.md
vendored
@@ -1,5 +1,4 @@
|
||||
### Merge / deployment checklist
|
||||
|
||||
- [ ] Confirm this change is backwards compatible with existing workflows.
|
||||
- [ ] Confirm the [readme](https://github.com/github/codeql-action/blob/main/README.md) has been updated if necessary.
|
||||
- [ ] Confirm the [changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) has been updated if necessary.
|
||||
- [ ] Confirm the [readme](https://github.com/github/codeql-action/blob/master/README.md) has been updated if necessary.
|
||||
|
||||
98
.github/update-release-branch.py
vendored
98
.github/update-release-branch.py
vendored
@@ -4,17 +4,6 @@ import random
|
||||
import requests
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
import datetime
|
||||
import os
|
||||
|
||||
EMPTY_CHANGELOG = """# CodeQL Action and CodeQL Runner Changelog
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
No user facing changes.
|
||||
|
||||
"""
|
||||
|
||||
# The branch being merged from.
|
||||
# This is the one that contains day-to-day development work.
|
||||
@@ -46,7 +35,7 @@ def open_pr(repo, all_commits, short_main_sha, branch_name):
|
||||
commits_without_pull_requests = []
|
||||
for commit in all_commits:
|
||||
pr = get_pr_for_commit(repo, commit)
|
||||
|
||||
|
||||
if pr is None:
|
||||
commits_without_pull_requests.append(commit)
|
||||
elif not any(p for p in pull_requests if p.number == pr.number):
|
||||
@@ -58,42 +47,34 @@ def open_pr(repo, all_commits, short_main_sha, branch_name):
|
||||
# Sort PRs and commits by age
|
||||
pull_requests = sorted(pull_requests, key=lambda pr: pr.number)
|
||||
commits_without_pull_requests = sorted(commits_without_pull_requests, key=lambda c: c.commit.author.date)
|
||||
|
||||
|
||||
# Start constructing the body text
|
||||
body = []
|
||||
body.append('Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH)
|
||||
body = 'Merging ' + short_main_sha + ' into ' + LATEST_RELEASE_BRANCH
|
||||
|
||||
conductor = get_conductor(repo, pull_requests, commits_without_pull_requests)
|
||||
body.append('')
|
||||
body.append('Conductor for this PR is @' + conductor)
|
||||
body += '\n\nConductor for this PR is @' + conductor
|
||||
|
||||
# List all PRs merged
|
||||
if len(pull_requests) > 0:
|
||||
body.append('')
|
||||
body.append('Contains the following pull requests:')
|
||||
body += '\n\nContains the following pull requests:'
|
||||
for pr in pull_requests:
|
||||
merger = get_merger_of_pr(repo, pr)
|
||||
body.append('- #' + str(pr.number) + ' - ' + pr.title +' (@' + merger + ')')
|
||||
|
||||
body += '\n- #' + str(pr.number)
|
||||
body += ' - ' + pr.title
|
||||
body += ' (@' + merger + ')'
|
||||
|
||||
# List all commits not part of a PR
|
||||
if len(commits_without_pull_requests) > 0:
|
||||
body.append('')
|
||||
body.append('Contains the following commits not from a pull request:')
|
||||
body += '\n\nContains the following commits not from a pull request:'
|
||||
for commit in commits_without_pull_requests:
|
||||
body.append('- ' + commit.sha + ' - ' + get_truncated_commit_message(commit) + ' (@' + commit.author.login + ')')
|
||||
|
||||
body.append('')
|
||||
body.append('Please review the following:')
|
||||
body.append(' - [ ] The CHANGELOG displays the correct version and date.')
|
||||
body.append(' - [ ] The CHANGELOG includes all relevant, user-facing changes since the last release.')
|
||||
body.append(' - [ ] There are no unexpected commits being merged into the ' + LATEST_RELEASE_BRANCH + ' branch.')
|
||||
body.append(' - [ ] The docs team is aware of any documentation changes that need to be released.')
|
||||
body.append(' - [ ] The mergeback PR is merged back into ' + MAIN_BRANCH + ' after this PR is merged.')
|
||||
body += '\n- ' + commit.sha
|
||||
body += ' - ' + get_truncated_commit_message(commit)
|
||||
body += ' (@' + commit.author.login + ')'
|
||||
|
||||
title = 'Merge ' + MAIN_BRANCH + ' into ' + LATEST_RELEASE_BRANCH
|
||||
|
||||
# Create the pull request
|
||||
pr = repo.create_pull(title=title, body='\n'.join(body), head=branch_name, base=LATEST_RELEASE_BRANCH)
|
||||
pr = repo.create_pull(title=title, body=body, head=branch_name, base=LATEST_RELEASE_BRANCH)
|
||||
print('Created PR #' + str(pr.number))
|
||||
|
||||
# Assign the conductor
|
||||
@@ -105,7 +86,7 @@ def get_conductor(repo, pull_requests, other_commits):
|
||||
# If there are any PRs then use whoever merged the last one
|
||||
if len(pull_requests) > 0:
|
||||
return get_merger_of_pr(repo, pull_requests[-1])
|
||||
|
||||
|
||||
# Otherwise take the author of the latest commit
|
||||
return other_commits[-1].author.login
|
||||
|
||||
@@ -114,7 +95,7 @@ def get_conductor(repo, pull_requests, other_commits):
|
||||
# This will not include any commits that exist on the release branch
|
||||
# that aren't on main.
|
||||
def get_commit_difference(repo):
|
||||
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '..' + ORIGIN + '/' + MAIN_BRANCH).strip().split('\n')
|
||||
commits = run_git('log', '--pretty=format:%H', ORIGIN + '/' + LATEST_RELEASE_BRANCH + '...' + MAIN_BRANCH).strip().split('\n')
|
||||
|
||||
# Convert to full-fledged commit objects
|
||||
commits = [repo.get_commit(c) for c in commits]
|
||||
@@ -124,7 +105,7 @@ def get_commit_difference(repo):
|
||||
|
||||
# Is the given commit the automatic merge commit from when merging a PR
|
||||
def is_pr_merge_commit(commit):
|
||||
return commit.committer is not None and commit.committer.login == 'web-flow' and len(commit.parents) > 1
|
||||
return commit.committer.login == 'web-flow' and len(commit.parents) > 1
|
||||
|
||||
# Gets a copy of the commit message that should display nicely
|
||||
def get_truncated_commit_message(commit):
|
||||
@@ -138,12 +119,12 @@ def get_truncated_commit_message(commit):
|
||||
# Returns the PR object, or None if no PR could be found.
|
||||
def get_pr_for_commit(repo, commit):
|
||||
prs = commit.get_pulls()
|
||||
|
||||
|
||||
if prs.totalCount > 0:
|
||||
# In the case that there are multiple PRs, return the earliest one
|
||||
prs = list(prs)
|
||||
sorted_prs = sorted(prs, key=lambda pr: int(pr.number))
|
||||
return sorted_prs[0]
|
||||
sorted(prs, key=lambda pr: int(pr.number))
|
||||
return prs[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -154,28 +135,6 @@ def get_pr_for_commit(repo, commit):
|
||||
def get_merger_of_pr(repo, pr):
|
||||
return repo.get_commit(pr.merge_commit_sha).author.login
|
||||
|
||||
def get_current_version():
|
||||
with open('package.json', 'r') as f:
|
||||
return json.load(f)['version']
|
||||
|
||||
def get_today_string():
|
||||
today = datetime.datetime.today()
|
||||
return '{:%d %b %Y}'.format(today)
|
||||
|
||||
def update_changelog(version):
|
||||
if (os.path.exists('CHANGELOG.md')):
|
||||
content = ''
|
||||
with open('CHANGELOG.md', 'r') as f:
|
||||
content = f.read()
|
||||
else:
|
||||
content = EMPTY_CHANGELOG
|
||||
|
||||
newContent = content.replace('[UNRELEASED]', version + ' - ' + get_today_string(), 1)
|
||||
|
||||
with open('CHANGELOG.md', 'w') as f:
|
||||
f.write(newContent)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
raise Exception('Usage: update-release.branch.py <github token> <repository nwo>')
|
||||
@@ -183,11 +142,10 @@ def main():
|
||||
repository_nwo = sys.argv[2]
|
||||
|
||||
repo = Github(github_token).get_repo(repository_nwo)
|
||||
version = get_current_version()
|
||||
|
||||
# Print what we intend to go
|
||||
print('Considering difference between ' + MAIN_BRANCH + ' and ' + LATEST_RELEASE_BRANCH)
|
||||
short_main_sha = run_git('rev-parse', '--short', ORIGIN + '/' + MAIN_BRANCH).strip()
|
||||
short_main_sha = run_git('rev-parse', '--short', MAIN_BRANCH).strip()
|
||||
print('Current head of ' + MAIN_BRANCH + ' is ' + short_main_sha)
|
||||
|
||||
# See if there are any commits to merge in
|
||||
@@ -199,7 +157,7 @@ def main():
|
||||
# The branch name is based off of the name of branch being merged into
|
||||
# and the SHA of the branch being merged from. Thus if the branch already
|
||||
# exists we can assume we don't need to recreate it.
|
||||
new_branch_name = 'update-v' + version + '-' + short_main_sha
|
||||
new_branch_name = 'update-' + LATEST_RELEASE_BRANCH + '-' + short_main_sha
|
||||
print('Branch name is ' + new_branch_name)
|
||||
|
||||
# Check if the branch already exists. If so we can abort as this script
|
||||
@@ -207,18 +165,10 @@ def main():
|
||||
if branch_exists_on_remote(new_branch_name):
|
||||
print('Branch ' + new_branch_name + ' already exists. Nothing to do.')
|
||||
return
|
||||
|
||||
|
||||
# Create the new branch and push it to the remote
|
||||
print('Creating branch ' + new_branch_name)
|
||||
run_git('checkout', '-b', new_branch_name, ORIGIN + '/' + MAIN_BRANCH)
|
||||
|
||||
print('Updating changelog')
|
||||
update_changelog(version)
|
||||
|
||||
# Create a commit that updates the CHANGELOG
|
||||
run_git('add', 'CHANGELOG.md')
|
||||
run_git('commit', '-m', version)
|
||||
|
||||
run_git('checkout', '-b', new_branch_name, MAIN_BRANCH)
|
||||
run_git('push', ORIGIN, new_branch_name)
|
||||
|
||||
# Open a PR to update the branch
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Check Expected Release Files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/check-expected-release-files.yml
|
||||
- src/defaults.json
|
||||
|
||||
jobs:
|
||||
check-expected-release-files:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout CodeQL Action
|
||||
uses: actions/checkout@v2
|
||||
- name: Check Expected Release Files
|
||||
run: |
|
||||
bundle_version="$(cat "./src/defaults.json" | jq -r ".bundleVersion")"
|
||||
set -x
|
||||
for expected_file in "codeql-bundle.tar.gz" "codeql-bundle-linux64.tar.gz" "codeql-bundle-osx64.tar.gz" "codeql-bundle-win64.tar.gz" "codeql-runner-linux" "codeql-runner-macos" "codeql-runner-win.exe"; do
|
||||
curl --location --fail --head --request GET "https://github.com/github/codeql-action/releases/download/$bundle_version/$expected_file" > /dev/null
|
||||
done
|
||||
72
.github/workflows/codeql.yml
vendored
72
.github/workflows/codeql.yml
vendored
@@ -4,80 +4,28 @@ on:
|
||||
push:
|
||||
branches: [main, v1]
|
||||
pull_request:
|
||||
branches: [main, v1]
|
||||
|
||||
jobs:
|
||||
# Identify the CodeQL tool versions to use in the analysis job.
|
||||
check-codeql-versions:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
versions: ${{ steps.compare.outputs.versions }}
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Init with default CodeQL bundle from the VM image
|
||||
id: init-default
|
||||
uses: ./init
|
||||
with:
|
||||
languages: javascript
|
||||
- name: Remove empty database
|
||||
# allows us to run init a second time
|
||||
run: |
|
||||
rm -rf "$RUNNER_TEMP/codeql_databases"
|
||||
- name: Init with latest CodeQL bundle
|
||||
id: init-latest
|
||||
uses: ./init
|
||||
with:
|
||||
tools: latest
|
||||
languages: javascript
|
||||
- name: Compare default and latest CodeQL bundle versions
|
||||
id: compare
|
||||
env:
|
||||
CODEQL_DEFAULT: ${{ steps.init-default.outputs.codeql-path }}
|
||||
CODEQL_LATEST: ${{ steps.init-latest.outputs.codeql-path }}
|
||||
run: |
|
||||
CODEQL_VERSION_DEFAULT="$("$CODEQL_DEFAULT" version --format terse)"
|
||||
CODEQL_VERSION_LATEST="$("$CODEQL_LATEST" version --format terse)"
|
||||
echo "Default CodeQL bundle version is $CODEQL_VERSION_DEFAULT"
|
||||
echo "Latest CodeQL bundle version is $CODEQL_VERSION_LATEST"
|
||||
if [[ "$CODEQL_VERSION_DEFAULT" == "$CODEQL_VERSION_LATEST" ]]; then
|
||||
# Just use `tools: null` to avoid duplication in the analysis job.
|
||||
VERSIONS_JSON='[null]'
|
||||
else
|
||||
# Use both `tools: null` and `tools: latest` in the analysis job.
|
||||
VERSIONS_JSON='[null, "latest"]'
|
||||
fi
|
||||
# Output a JSON-encoded list with the distinct versions to test against.
|
||||
echo "Suggested matrix config for analysis job: $VERSIONS_JSON"
|
||||
echo "::set-output name=versions::${VERSIONS_JSON}"
|
||||
|
||||
build:
|
||||
needs: [check-codeql-versions]
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest,windows-latest,macos-latest]
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
# Must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head of the pull request.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- uses: ./init
|
||||
id: init
|
||||
with:
|
||||
languages: javascript
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
tools: ${{ matrix.tools }}
|
||||
# confirm steps.init.outputs.codeql-path points to the codeql binary
|
||||
- name: Print CodeQL Version
|
||||
run: ${{steps.init.outputs.codeql-path}} version --format=json
|
||||
- uses: ./analyze
|
||||
|
||||
449
.github/workflows/integration-testing.yml
vendored
Normal file
449
.github/workflows/integration-testing.yml
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
name: "Integration Testing"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, v1]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
multi-language-repo_test-autodetect-languages:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
- uses: ./../action/init
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- run: |
|
||||
cd "$RUNNER_TEMP/codeql_databases"
|
||||
# List all directories as there will be precisely one directory per database
|
||||
# but there may be other files in this directory such as query suites.
|
||||
if [ "$(ls -d */ | wc -l)" != 6 ] || \
|
||||
[[ ! -d cpp ]] || \
|
||||
[[ ! -d csharp ]] || \
|
||||
[[ ! -d go ]] || \
|
||||
[[ ! -d java ]] || \
|
||||
[[ ! -d javascript ]] || \
|
||||
[[ ! -d python ]]; then
|
||||
echo "Did not find expected number of databases. Database dir contains: $(ls)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
multi-language-repo_test-custom-queries-and-remote-config:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
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} .
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: cpp,csharp,java,javascript,python
|
||||
config-file: github/codeql-action/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
# Currently is not possible to analyze Go in conjunction with other languages in macos
|
||||
multi-language-repo_test-go-custom-queries:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
with:
|
||||
go-version: '^1.13.1'
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: go
|
||||
config-file: ./.github/codeql/custom-queries.yml
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
multi-language-repo_rubocop:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install
|
||||
- name: Install dependencies
|
||||
run: bundle install
|
||||
- name: Rubocop run
|
||||
run: |
|
||||
bash -c "
|
||||
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
||||
[[ $? -ne 2 ]]
|
||||
"
|
||||
- uses: ./../action/upload-sarif
|
||||
with:
|
||||
sarif_file: rubocop.sarif
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
test-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:18.04
|
||||
options: --dns 127.0.0.1
|
||||
services:
|
||||
squid-proxy:
|
||||
image: datadog/squid:latest
|
||||
ports:
|
||||
- 3128:3128
|
||||
env:
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: javascript
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
# Pass --config-file here, but not for other jobs in this workflow.
|
||||
# This means we're testing the config file parsing in the runner
|
||||
# but not slowing down all jobs unnecessarily as it doesn't add much
|
||||
# testing the parsing on different operating systems and languages.
|
||||
runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages javascript --config-file ./.github/codeql/codeql-config.yml --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages javascript --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages javascript --config-file ./.github/codeql/codeql-config.yml --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
run: |
|
||||
. ./codeql-runner/codeql-env.sh
|
||||
dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages csharp --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: powershell
|
||||
run: |
|
||||
cat ./codeql-runner/codeql-env.sh | Invoke-Expression
|
||||
dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: |
|
||||
. ./codeql-runner/codeql-env.sh
|
||||
dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
|
||||
runner-analyze-csharp-autobuild-ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-autobuild-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages csharp --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: powershell
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-autobuild-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-upload-sarif:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Upload with runner
|
||||
run: |
|
||||
# Deliberately don't use TEST_MODE here. This is specifically testing
|
||||
# the compatibility with the API.
|
||||
runner/dist/codeql-runner-linux upload --sarif-file src/testdata/empty-sarif.sarif --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
123
.github/workflows/post-release-mergeback.yml
vendored
123
.github/workflows/post-release-mergeback.yml
vendored
@@ -1,123 +0,0 @@
|
||||
# This workflow runs after a release of the action.
|
||||
# It merges any changes from the release back into the
|
||||
# main branch. Typically, this is just a single commit
|
||||
# that updates the changelog.
|
||||
name: Tag release and merge back
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
baseBranch:
|
||||
description: 'The base branch to merge into'
|
||||
default: main
|
||||
required: false
|
||||
|
||||
push:
|
||||
branches:
|
||||
- v1
|
||||
|
||||
jobs:
|
||||
merge-back:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'github/codeql-action'
|
||||
env:
|
||||
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'main' }}"
|
||||
HEAD_BRANCH: "${{ github.head_ref || github.ref }}"
|
||||
|
||||
steps:
|
||||
- name: Dump GitHub Event context
|
||||
env:
|
||||
GITHUB_EVENT_CONTEXT: "${{ toJson(github.event) }}"
|
||||
run: echo "$GITHUB_EVENT_CONTEXT"
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
|
||||
- name: Update git config
|
||||
run: |
|
||||
git config --global user.email "github-actions@github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
|
||||
- name: Get version and new branch
|
||||
id: getVersion
|
||||
run: |
|
||||
VERSION="v$(jq '.version' -r 'package.json')"
|
||||
SHORT_SHA="${GITHUB_SHA:0:8}"
|
||||
echo "::set-output name=version::$VERSION"
|
||||
NEW_BRANCH="mergeback/${VERSION}-to-${BASE_BRANCH}-${SHORT_SHA}"
|
||||
echo "::set-output name=newBranch::$NEW_BRANCH"
|
||||
|
||||
|
||||
- name: Dump branches
|
||||
env:
|
||||
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
||||
run: |
|
||||
echo "BASE_BRANCH $BASE_BRANCH"
|
||||
echo "HEAD_BRANCH $HEAD_BRANCH"
|
||||
echo "NEW_BRANCH $NEW_BRANCH"
|
||||
|
||||
- name: Create mergeback branch
|
||||
env:
|
||||
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
||||
run: |
|
||||
git checkout -b "$NEW_BRANCH"
|
||||
|
||||
- name: Check for tag
|
||||
id: check
|
||||
env:
|
||||
VERSION: "${{ steps.getVersion.outputs.version }}"
|
||||
run: |
|
||||
set +e # don't fail on an errored command
|
||||
git ls-remote --tags origin | grep "$VERSION"
|
||||
EXISTS="$?"
|
||||
if [ "$EXISTS" -eq 0 ]; then
|
||||
echo "Tag $TAG exists. Not going to re-release."
|
||||
echo "::set-output name=exists::true"
|
||||
else
|
||||
echo "Tag $TAG does not exist yet."
|
||||
fi
|
||||
|
||||
# we didn't tag the release during the update-release-branch workflow because the
|
||||
# commit that actually makes it to the release branch is a merge commit,
|
||||
# and not yet known during the first workflow. We tag now because we know the correct commit.
|
||||
- name: Tag release
|
||||
if: steps.check.outputs.exists != 'true'
|
||||
env:
|
||||
VERSION: ${{ steps.getVersion.outputs.version }}
|
||||
run: |
|
||||
git tag -a "$VERSION" -m "$VERSION"
|
||||
git fetch --unshallow # unshallow the repo in order to allow pushes
|
||||
git push origin --follow-tags "$VERSION"
|
||||
|
||||
- name: Create mergeback branch
|
||||
if: steps.check.outputs.exists != 'true'
|
||||
env:
|
||||
VERSION: "${{ steps.getVersion.outputs.version }}"
|
||||
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
run: |
|
||||
set -exu
|
||||
PR_TITLE="Mergeback $VERSION $HEAD_BRANCH into $BASE_BRANCH"
|
||||
PR_BODY="Updates version and changelog."
|
||||
|
||||
# Update the changelog
|
||||
perl -i -pe 's/^/## \[UNRELEASED\]\n\nNo user facing changes.\n\n/ if($.==3)' CHANGELOG.md
|
||||
git add .
|
||||
git commit -m "Update changelog and version after $VERSION"
|
||||
npm version patch
|
||||
|
||||
# when running this workflow on a PR, this is just a test.
|
||||
# so put into draft mode.
|
||||
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
|
||||
DRAFT="--draft"
|
||||
else
|
||||
DRAFT=""
|
||||
fi
|
||||
|
||||
git push origin "$NEW_BRANCH"
|
||||
gh pr create \
|
||||
--head "$NEW_BRANCH" \
|
||||
--base "$BASE_BRANCH" \
|
||||
--title "$PR_TITLE" \
|
||||
--body "$PR_BODY" \
|
||||
${DRAFT:+"$DRAFT"} # no quotes around $DRAFT. gh will error out if there is an empty ""
|
||||
894
.github/workflows/pr-checks.yml
vendored
894
.github/workflows/pr-checks.yml
vendored
@@ -1,13 +1,9 @@
|
||||
name: "PR checks"
|
||||
|
||||
env:
|
||||
GO111MODULE: auto
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, v1]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
lint-js:
|
||||
@@ -24,7 +20,25 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Check generated JavaScript
|
||||
run: .github/workflows/script/check-js.sh
|
||||
run: |
|
||||
# Sanity check that repo is clean to start with
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then this workflow needs attention...
|
||||
>&2 echo "Failed: Repo should be clean before testing!"
|
||||
exit 1
|
||||
fi
|
||||
# Wipe the lib directory incase there are extra unnecessary files in there
|
||||
rm -rf lib
|
||||
# Generate the JavaScript files
|
||||
npm run-script build
|
||||
# Check that repo is still clean
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then the PR needs attention
|
||||
>&2 echo "Failed: JavaScript files are not up to date. Run 'npm run-script build' to update"
|
||||
git status
|
||||
exit 1
|
||||
fi
|
||||
echo "Success: JavaScript files are up to date"
|
||||
|
||||
check-node-modules:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -32,10 +46,27 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Check node modules up to date
|
||||
run: .github/workflows/script/check-node-modules.sh
|
||||
run: |
|
||||
# Sanity check that repo is clean to start with
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then this workflow needs attention...
|
||||
>&2 echo "Failed: Repo should be clean before testing!"
|
||||
exit 1
|
||||
fi
|
||||
# Reinstall modules and then clean to remove absolute paths
|
||||
# Use 'npm ci' instead of 'npm install' as this is intended to be reproducible
|
||||
npm ci
|
||||
npm run removeNPMAbsolutePaths
|
||||
# Check that repo is still clean
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then the PR needs attention
|
||||
>&2 echo "Failed: node_modules are not up to date. Run 'npm ci' and 'npm run removeNPMAbsolutePaths' to update"
|
||||
git status
|
||||
exit 1
|
||||
fi
|
||||
echo "Success: node_modules are up to date"
|
||||
|
||||
npm-test:
|
||||
needs: [check-js, check-node-modules]
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest,macos-latest]
|
||||
@@ -45,852 +76,3 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- name: npm run-script test
|
||||
run: npm run-script test
|
||||
|
||||
multi-language-repo_test-autodetect-languages:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
db-location: "${{ runner.temp }}/customDbLocation"
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
id: analysis
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- run: |
|
||||
CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }}
|
||||
if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for CPP, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
CSHARP_DB=${{ fromJson(steps.analysis.outputs.db-locations).csharp }}
|
||||
if [[ ! -d $CSHARP_DB ]] || [[ ! $CSHARP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for C Sharp, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
GO_DB=${{ fromJson(steps.analysis.outputs.db-locations).go }}
|
||||
if [[ ! -d $GO_DB ]] || [[ ! $GO_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for Go, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
JAVA_DB=${{ fromJson(steps.analysis.outputs.db-locations).java }}
|
||||
if [[ ! -d $JAVA_DB ]] || [[ ! $JAVA_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for Java, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
JAVASCRIPT_DB=${{ fromJson(steps.analysis.outputs.db-locations).javascript }}
|
||||
if [[ ! -d $JAVASCRIPT_DB ]] || [[ ! $JAVASCRIPT_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for Javascript, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
PYTHON_DB=${{ fromJson(steps.analysis.outputs.db-locations).python }}
|
||||
if [[ ! -d $PYTHON_DB ]] || [[ ! $PYTHON_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||
echo "Did not create a database for Python, or created it in the wrong location."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Packaging test that runs against a javascript database
|
||||
# Specifying packs in the config file.
|
||||
test-packaging-javascript-config:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
config-file: ".github/codeql/codeql-config-packaging.yml"
|
||||
languages: javascript
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: "${{ runner.temp }}/results"
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Assert Results
|
||||
run: |
|
||||
cd "$RUNNER_TEMP/results"
|
||||
# We should have 3 hits from these rules
|
||||
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
|
||||
|
||||
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
|
||||
echo "Found matching rules '$RULES'"
|
||||
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Packaging test that runs against a javascript database
|
||||
# Specifying packs as an input.
|
||||
test-packaging-javascript-inputs:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
config-file: ".github/codeql/codeql-config-packaging2.yml"
|
||||
languages: javascript
|
||||
packs: dsp-testing/codeql-pack1@0.0.4, dsp-testing/codeql-pack2
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: "${{ runner.temp }}/results"
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Assert Results
|
||||
run: |
|
||||
cd "$RUNNER_TEMP/results"
|
||||
# We should have 3 hits from these rules
|
||||
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
|
||||
|
||||
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
|
||||
echo "Found matching rules '$RULES'"
|
||||
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Packaging test that runs against a javascript database
|
||||
# Specifying packs in the config file and inputs.
|
||||
test-packaging-javascript-config-and-inputs:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
config-file: ".github/codeql/codeql-config-packaging3.yml"
|
||||
packs: +dsp-testing/codeql-pack1@0.0.4
|
||||
languages: javascript
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: "${{ runner.temp }}/results"
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Assert Results
|
||||
run: |
|
||||
cd "$RUNNER_TEMP/results"
|
||||
# We should have 3 hits from these rules
|
||||
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
|
||||
|
||||
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
|
||||
echo "Found matching rules '$RULES'"
|
||||
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Tests a split workflow where database construction and query execution happen in different steps
|
||||
test-split-workflow:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
config-file: ".github/codeql/codeql-config-packaging3.yml"
|
||||
packs: +dsp-testing/codeql-pack1@0.0.4
|
||||
languages: javascript
|
||||
tools: latest
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
skip-queries: true
|
||||
output: "${{ runner.temp }}/results"
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Assert No Results
|
||||
run: |
|
||||
if [ "$(ls -A $RUNNER_TEMP/results)" ]; then
|
||||
echo "Expected results directory to be empty after skipping query execution!"
|
||||
exit 1
|
||||
fi
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: "${{ runner.temp }}/results"
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- name: Assert Results
|
||||
run: |
|
||||
cd "$RUNNER_TEMP/results"
|
||||
# We should have 3 hits from these rules
|
||||
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/two-block"
|
||||
|
||||
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n" " " | xargs)"
|
||||
echo "Found matching rules '$RULES'"
|
||||
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Identify the CodeQL tool versions to integration test against.
|
||||
check-codeql-versions:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
versions: ${{ steps.compare.outputs.versions }}
|
||||
nightly-url: ${{ steps.get-url.outputs.nightly-url }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- name: Init with default CodeQL bundle from the VM image
|
||||
id: init-default
|
||||
uses: ./../action/init
|
||||
with:
|
||||
languages: javascript
|
||||
- name: Remove empty database
|
||||
# allows us to run init a second time
|
||||
run: |
|
||||
rm -rf "$RUNNER_TEMP/codeql_databases"
|
||||
- name: Init with latest CodeQL bundle
|
||||
id: init-latest
|
||||
uses: ./../action/init
|
||||
with:
|
||||
tools: latest
|
||||
languages: javascript
|
||||
- name: Remove empty database
|
||||
# allows us to run init a third time
|
||||
run: |
|
||||
rm -rf "$RUNNER_TEMP/codeql_databases"
|
||||
- name: Get nightly release URL
|
||||
id: get-url
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
shell: bash
|
||||
# This workflow step gets an unstable testing version of the CodeQL CLI. It should not be used outside of these tests.
|
||||
run: |
|
||||
export LATEST=`gh release list --repo dsp-testing/codeql-cli-nightlies -L 1 | cut -f 3`
|
||||
echo "::set-output name=nightly-url::https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/$LATEST/codeql-bundle.tar.gz"
|
||||
- name: Init with a CodeQL bundle from a nightly release
|
||||
id: init-nightly
|
||||
uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ steps.get-url.outputs.nightly-url }}
|
||||
languages: javascript
|
||||
- name: Compare CodeQL bundle versions
|
||||
id: compare
|
||||
env:
|
||||
CODEQL_DEFAULT: ${{ steps.init-default.outputs.codeql-path }}
|
||||
CODEQL_LATEST: ${{ steps.init-latest.outputs.codeql-path }}
|
||||
CODEQL_NIGHTLY: ${{ steps.init-nightly.outputs.codeql-path }}
|
||||
NIGHTLY_URL: ${{ steps.get-url.outputs.nightly-url }}
|
||||
run: |
|
||||
CODEQL_VERSION_DEFAULT="$("$CODEQL_DEFAULT" version --format terse)"
|
||||
CODEQL_VERSION_LATEST="$("$CODEQL_LATEST" version --format terse)"
|
||||
CODEQL_VERSION_NIGHTLY="$("$CODEQL_NIGHTLY" version --format terse)"
|
||||
echo "Default CodeQL bundle version is $CODEQL_VERSION_DEFAULT"
|
||||
echo "Latest CodeQL bundle version is $CODEQL_VERSION_LATEST"
|
||||
echo "Nightly CodeQL bundle version is $CODEQL_VERSION_NIGHTLY"
|
||||
if [[ "$CODEQL_VERSION_DEFAULT" == "$CODEQL_VERSION_LATEST" ]]; then
|
||||
# Skip `tools: latest` since it would be the same as `tools: null`
|
||||
VERSIONS_JSON="[null, \"$NIGHTLY_URL\"]"
|
||||
else
|
||||
# Run integration tests with all three bundles.
|
||||
VERSIONS_JSON="[null, \"$NIGHTLY_URL\", \"latest\"]"
|
||||
fi
|
||||
# Output a JSON-encoded list with the distinct versions to test against.
|
||||
echo "Suggested matrix config for integration tests: $VERSIONS_JSON"
|
||||
echo "::set-output name=versions::${VERSIONS_JSON}"
|
||||
|
||||
multi-language-repo_test-custom-queries-and-remote-config:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
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} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ matrix.tools }}
|
||||
languages: cpp,csharp,java,javascript,python
|
||||
config-file: github/codeql-action/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
# Currently is not possible to analyze Go in conjunction with other languages in macos
|
||||
multi-language-repo_test-go-custom-queries:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
with:
|
||||
go-version: '^1.13.1'
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: go
|
||||
config-file: ./.github/codeql/custom-queries.yml
|
||||
tools: ${{ matrix.tools }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
go-custom-tracing:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CODEQL_EXTRACTOR_GO_BUILD_TRACING: "on"
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
with:
|
||||
go-version: '^1.13.1'
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: go
|
||||
tools: ${{ matrix.tools }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: go build main.go
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
go-custom-tracing-autobuild:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
# No need to test Go autobuild on multiple OSes since
|
||||
# we're testing Go custom tracing with a manual build on all OSes.
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CODEQL_EXTRACTOR_GO_BUILD_TRACING: "on"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: go
|
||||
tools: ${{ matrix.tools }}
|
||||
- uses: ./../action/autobuild
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
- run: |
|
||||
cd "$RUNNER_TEMP/codeql_databases"
|
||||
if [[ ! -d go ]]; then
|
||||
echo "Did not find a Go database"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
multi-language-repo_rubocop:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install
|
||||
- name: Install dependencies
|
||||
run: bundle install
|
||||
- name: Rubocop run
|
||||
run: |
|
||||
bash -c "
|
||||
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
|
||||
[[ $? -ne 2 ]]
|
||||
"
|
||||
- uses: ./../action/upload-sarif
|
||||
with:
|
||||
sarif_file: rubocop.sarif
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
test-proxy:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:18.04
|
||||
options: --dns 127.0.0.1
|
||||
services:
|
||||
squid-proxy:
|
||||
image: datadog/squid:latest
|
||||
ports:
|
||||
- 3128:3128
|
||||
env:
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
languages: javascript
|
||||
tools: ${{ matrix.tools }}
|
||||
- uses: ./../action/analyze
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-ubuntu:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
# Pass --config-file here, but not for other jobs in this workflow.
|
||||
# This means we're testing the config file parsing in the runner
|
||||
# but not slowing down all jobs unnecessarily as it doesn't add much
|
||||
# testing the parsing on different operating systems and languages.
|
||||
runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages javascript --config-file ./.github/codeql/codeql-config.yml --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-windows:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages javascript --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-javascript-macos:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages javascript --config-file ./.github/codeql/codeql-config.yml --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-ubuntu:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
run: |
|
||||
. ./codeql-runner/codeql-env.sh
|
||||
$CODEQL_RUNNER dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-windows:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages csharp --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: powershell
|
||||
# Note we want to make sure that the .win32env file is read correctly, so we unset the CODEQL_EXTRACTOR_CSHARP_ROOT from the .sh file.
|
||||
run: |
|
||||
cat ./codeql-runner/codeql-env.sh | Invoke-Expression
|
||||
$Env:CODEQL_EXTRACTOR_CSHARP_ROOT = ""
|
||||
& $Env:CODEQL_RUNNER dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-macos:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: |
|
||||
. ./codeql-runner/codeql-env.sh
|
||||
$CODEQL_RUNNER dotnet build
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
|
||||
runner-analyze-csharp-autobuild-ubuntu:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-linux analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-autobuild-windows:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe init --repository $Env:GITHUB_REPOSITORY --languages csharp --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: powershell
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-win.exe analyze --repository $Env:GITHUB_REPOSITORY --commit $Env:GITHUB_SHA --ref $Env:GITHUB_REF --github-url $Env:GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-analyze-csharp-autobuild-macos:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Move codeql-action
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd ../action/runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Run init
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos init --repository $GITHUB_REPOSITORY --languages csharp --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos autobuild
|
||||
|
||||
- name: Run analyze
|
||||
run: |
|
||||
../action/runner/dist/codeql-runner-macos analyze --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
env:
|
||||
TEST_MODE: true
|
||||
|
||||
runner-upload-sarif:
|
||||
needs: [check-js, check-node-modules]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- name: Upload with runner
|
||||
run: |
|
||||
# Deliberately don't use TEST_MODE here. This is specifically testing
|
||||
# the compatibility with the API.
|
||||
runner/dist/codeql-runner-linux upload --sarif-file src/testdata/empty-sarif.sarif --repository $GITHUB_REPOSITORY --commit $GITHUB_SHA --ref $GITHUB_REF --github-url $GITHUB_SERVER_URL --github-auth ${{ github.token }}
|
||||
|
||||
multi-language-repo_test-local-codeql:
|
||||
needs: [check-js, check-node-modules, check-codeql-versions]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Move codeql-action
|
||||
run: |
|
||||
wget ${{ needs.check-codeql-versions.outputs.nightly-url }}
|
||||
mkdir ../action
|
||||
mv * .github ../action/
|
||||
mv ../action/tests/multi-language-repo/{*,.github} .
|
||||
mv ../action/.github/workflows .github
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ../action/codeql-bundle.tar.gz
|
||||
- name: Build code
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
|
||||
152
.github/workflows/python-deps.yml
vendored
152
.github/workflows/python-deps.yml
vendored
@@ -1,150 +1,64 @@
|
||||
name: Test Python Package Installation on Linux and Mac
|
||||
name: Test Python Package Installation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, v1]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
test-setup-python-scripts:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
||||
python_version: [2, 3]
|
||||
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
|
||||
|
||||
env:
|
||||
PYTHON_DEPS_TYPE: ${{ matrix.python_deps_type }}
|
||||
PYTHON_VERSION: ${{ matrix.python_version }}
|
||||
- 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: ./init
|
||||
id: init
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
tools: latest
|
||||
languages: python
|
||||
setup-python-dependencies: false
|
||||
|
||||
- name: Test Auto Package Installation
|
||||
run: |
|
||||
set -x
|
||||
$GITHUB_WORKSPACE/python-setup/install_tools.sh
|
||||
|
||||
cd $GITHUB_WORKSPACE/python-setup/tests/${PYTHON_DEPS_TYPE}/requests-${PYTHON_VERSION}
|
||||
|
||||
case ${{ matrix.os }} in
|
||||
ubuntu-latest*) basePath="/opt";;
|
||||
macos-latest*) basePath="/Users/runner";;
|
||||
esac
|
||||
echo ${basePath}
|
||||
|
||||
$GITHUB_WORKSPACE/python-setup/auto_install_packages.py "$(dirname ${{steps.init.outputs.codeql-path}})"
|
||||
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
|
||||
if [ ! -z $CODEQL_PYTHON ]; then
|
||||
$GITHUB_WORKSPACE/python-setup/tests/from_python_exe.py $CODEQL_PYTHON;
|
||||
fi
|
||||
|
||||
test ! -z $CODEQL_PYTHON && $GITHUB_WORKSPACE/python-setup/tests/from_python_exe.py $CODEQL_PYTHON || /bin/true
|
||||
- name: Verify packages installed
|
||||
run: |
|
||||
$GITHUB_WORKSPACE/python-setup/tests/check_requests_123.sh ${PYTHON_VERSION}
|
||||
|
||||
# This one shouldn't fail, but also won't install packages
|
||||
test-setup-python-scripts-non-standard-location:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: ./init
|
||||
id: init
|
||||
with:
|
||||
tools: latest
|
||||
languages: python
|
||||
setup-python-dependencies: false
|
||||
|
||||
- name: Test Auto Package Installation
|
||||
run: |
|
||||
set -x
|
||||
$GITHUB_WORKSPACE/python-setup/install_tools.sh
|
||||
|
||||
cd $GITHUB_WORKSPACE/python-setup/tests/requirements/non-standard-location
|
||||
|
||||
case ${{ matrix.os }} in
|
||||
ubuntu-latest*) basePath="/opt";;
|
||||
macos-latest*) basePath="/Users/runner";;
|
||||
esac
|
||||
echo ${basePath}
|
||||
|
||||
$GITHUB_WORKSPACE/python-setup/auto_install_packages.py "$(dirname ${{steps.init.outputs.codeql-path}})"
|
||||
|
||||
- name: Setup for extractor
|
||||
run: |
|
||||
echo $CODEQL_PYTHON
|
||||
# only run if $CODEQL_PYTHON is set
|
||||
if [ ! -z $CODEQL_PYTHON ]; then
|
||||
$GITHUB_WORKSPACE/python-setup/tests/from_python_exe.py $CODEQL_PYTHON;
|
||||
fi
|
||||
|
||||
- name: Verify packages installed
|
||||
run: |
|
||||
test -z $LGTM_INDEX_IMPORT_PATH
|
||||
|
||||
test-setup-python-scripts-windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
||||
python_version: [2, 3]
|
||||
|
||||
env:
|
||||
PYTHON_DEPS_TYPE: ${{ matrix.python_deps_type }}
|
||||
PYTHON_VERSION: ${{ matrix.python_version }}
|
||||
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: ./init
|
||||
with:
|
||||
tools: latest
|
||||
languages: python
|
||||
setup-python-dependencies: false
|
||||
|
||||
- name: Test Auto Package Installation
|
||||
run: |
|
||||
$cmd = $Env:GITHUB_WORKSPACE + "\\python-setup\\install_tools.ps1"
|
||||
powershell -File $cmd
|
||||
|
||||
cd $Env:GITHUB_WORKSPACE\\python-setup/tests/$Env:PYTHON_DEPS_TYPE/requests-$Env:PYTHON_VERSION
|
||||
$DefaultsPath = Join-Path (Join-Path $Env:GITHUB_WORKSPACE "src") "defaults.json"
|
||||
$CodeQLBundleName = (Get-Content -Raw -Path $DefaultsPath | ConvertFrom-Json).bundleVersion
|
||||
$CodeQLVersion = "0.0.0-" + $CodeQLBundleName.split("-")[-1]
|
||||
py -3 $Env:GITHUB_WORKSPACE\\python-setup\\auto_install_packages.py C:\\hostedtoolcache\\windows\\CodeQL\\$CodeQLVersion\\x64\\codeql
|
||||
|
||||
- name: Setup for extractor
|
||||
run: |
|
||||
echo $Env:CODEQL_PYTHON
|
||||
|
||||
py -3 $Env:GITHUB_WORKSPACE\\python-setup\\tests\\from_python_exe.py $Env:CODEQL_PYTHON
|
||||
|
||||
- name: Verify packages installed
|
||||
run: |
|
||||
$cmd = $Env:GITHUB_WORKSPACE + "\\python-setup\\tests\\check_requests_123.ps1"
|
||||
powershell -File $cmd $Env:PYTHON_VERSION
|
||||
${{ matrix.test_script }}
|
||||
54
.github/workflows/release-runner.yml
vendored
54
.github/workflows/release-runner.yml
vendored
@@ -1,54 +0,0 @@
|
||||
name: Release runner
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
bundle-tag:
|
||||
description: 'Tag of the bundle release (e.g., "codeql-bundle-20200826")'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
release-runner:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RELEASE_TAG: "${{ github.event.inputs.bundle-tag }}"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
extension: ["linux", "macos", "win.exe"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build runner
|
||||
run: |
|
||||
cd runner
|
||||
npm install
|
||||
npm run build-runner
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: codeql-runner-${{matrix.extension}}
|
||||
path: runner/dist/codeql-runner-${{matrix.extension}}
|
||||
|
||||
- name: Resolve Upload URL for the release
|
||||
if: ${{ github.event.inputs.bundle-tag != null }}
|
||||
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: Upload Platform Package
|
||||
if: ${{ github.event.inputs.bundle-tag != null }}
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.save_url.outputs.upload_url }}
|
||||
asset_path: runner/dist/codeql-runner-${{matrix.extension}}
|
||||
asset_name: codeql-runner-${{matrix.extension}}
|
||||
asset_content_type: application/octet-stream
|
||||
21
.github/workflows/script/check-js.sh
vendored
21
.github/workflows/script/check-js.sh
vendored
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
# Sanity check that repo is clean to start with
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then this workflow needs attention...
|
||||
>&2 echo "Failed: Repo should be clean before testing!"
|
||||
exit 1
|
||||
fi
|
||||
# Wipe the lib directory incase there are extra unnecessary files in there
|
||||
rm -rf lib
|
||||
# Generate the JavaScript files
|
||||
npm run-script build
|
||||
# Check that repo is still clean
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then the PR needs attention
|
||||
>&2 echo "Failed: JavaScript files are not up to date. Run 'npm run-script build' to update"
|
||||
git status
|
||||
exit 1
|
||||
fi
|
||||
echo "Success: JavaScript files are up to date"
|
||||
21
.github/workflows/script/check-node-modules.sh
vendored
21
.github/workflows/script/check-node-modules.sh
vendored
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
# Sanity check that repo is clean to start with
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then this workflow needs attention...
|
||||
>&2 echo "Failed: Repo should be clean before testing!"
|
||||
exit 1
|
||||
fi
|
||||
# Reinstall modules and then clean to remove absolute paths
|
||||
# Use 'npm ci' instead of 'npm install' as this is intended to be reproducible
|
||||
npm ci
|
||||
npm run removeNPMAbsolutePaths
|
||||
# Check that repo is still clean
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
# If we get a fail here then the PR needs attention
|
||||
>&2 echo "Failed: node_modules are not up to date. Run 'npm ci && npm run removeNPMAbsolutePaths' on a macOS machine to update. Note it is important this command is run on macOS and not any other operating system as there is one dependency (fsevents) that is needed for macOS and may not be installed if the command is run on a Windows or Linux machine."
|
||||
git status
|
||||
exit 1
|
||||
fi
|
||||
echo "Success: node_modules are up to date"
|
||||
8
.github/workflows/update-release-branch.yml
vendored
8
.github/workflows/update-release-branch.yml
vendored
@@ -12,7 +12,6 @@ on:
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'github/codeql-action' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -22,17 +21,12 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
python-version: 3.5
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install PyGithub==1.51 requests
|
||||
|
||||
- name: Update git config
|
||||
run: |
|
||||
git config --global user.email "github-actions@github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
|
||||
- name: Update release branch
|
||||
run: python .github/update-release-branch.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
name: Update Supported Enterprise Server Versions
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
update-supported-enterprise-server-versions:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'github/codeql-action' }}
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.7"
|
||||
- name: Checkout CodeQL Action
|
||||
uses: actions/checkout@v2
|
||||
- name: Checkout Enterprise Releases
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: github/enterprise-releases
|
||||
ssh-key: ${{ secrets.ENTERPRISE_RELEASES_SSH_KEY }}
|
||||
path: ${{ github.workspace }}/enterprise-releases/
|
||||
- name: Update Supported Enterprise Server Versions
|
||||
run: |
|
||||
cd ./.github/workflows/update-supported-enterprise-server-versions/
|
||||
python3 -m pip install pipenv
|
||||
pipenv install
|
||||
pipenv run ./update.py
|
||||
rm --recursive "$ENTERPRISE_RELEASES_PATH"
|
||||
npm run build
|
||||
env:
|
||||
ENTERPRISE_RELEASES_PATH: ${{ github.workspace }}/enterprise-releases/
|
||||
- name: Commit Changes
|
||||
uses: peter-evans/create-pull-request@c7f493a8000b8aeb17a1332e326ba76b57cb83eb # v3.4.1
|
||||
with:
|
||||
commit-message: Update supported GitHub Enterprise Server versions.
|
||||
title: Update supported GitHub Enterprise Server versions.
|
||||
body: ""
|
||||
author: GitHub <noreply@github.com>
|
||||
branch: update-supported-enterprise-server-versions
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
import semver
|
||||
|
||||
_API_COMPATIBILITY_PATH = pathlib.Path(__file__).absolute().parents[3] / "src" / "api-compatibility.json"
|
||||
_ENTERPRISE_RELEASES_PATH = pathlib.Path(os.environ["ENTERPRISE_RELEASES_PATH"])
|
||||
_RELEASE_FILE_PATH = _ENTERPRISE_RELEASES_PATH / "releases.json"
|
||||
_FIRST_SUPPORTED_RELEASE = semver.VersionInfo.parse("2.22.0") # Versions older than this did not include Code Scanning.
|
||||
|
||||
def main():
|
||||
api_compatibility_data = json.loads(_API_COMPATIBILITY_PATH.read_text())
|
||||
|
||||
releases = json.loads(_RELEASE_FILE_PATH.read_text())
|
||||
oldest_supported_release = None
|
||||
newest_supported_release = semver.VersionInfo.parse(api_compatibility_data["maximumVersion"] + ".0")
|
||||
|
||||
for release_version_string, release_data in releases.items():
|
||||
release_version = semver.VersionInfo.parse(release_version_string + ".0")
|
||||
if release_version < _FIRST_SUPPORTED_RELEASE:
|
||||
continue
|
||||
|
||||
if release_version > newest_supported_release:
|
||||
feature_freeze_date = datetime.date.fromisoformat(release_data["feature_freeze"])
|
||||
if feature_freeze_date < datetime.date.today() + datetime.timedelta(weeks=2):
|
||||
newest_supported_release = release_version
|
||||
|
||||
if oldest_supported_release is None or release_version < oldest_supported_release:
|
||||
end_of_life_date = datetime.date.fromisoformat(release_data["end"])
|
||||
if end_of_life_date > datetime.date.today():
|
||||
oldest_supported_release = release_version
|
||||
|
||||
api_compatibility_data = {
|
||||
"minimumVersion": f"{oldest_supported_release.major}.{oldest_supported_release.minor}",
|
||||
"maximumVersion": f"{newest_supported_release.major}.{newest_supported_release.minor}",
|
||||
}
|
||||
_API_COMPATIBILITY_PATH.write_text(json.dumps(api_compatibility_data, sort_keys=True) + "\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
15
.vscode/tasks.json
vendored
15
.vscode/tasks.json
vendored
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tsc: watch - tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,32 +0,0 @@
|
||||
# CodeQL Action and CodeQL Runner Changelog
|
||||
|
||||
## 1.0.5 - 12 Jul 2021
|
||||
|
||||
- The `analyze` step of the Action now supports a `skip-queries` option to merely build the CodeQL database without analyzing. This functionality is not present in the runner. Additionally, the step will no longer fail if it encounters a finalized database, and will instead continue with query execution. [#602](https://github.com/github/codeql-action/pull/602)
|
||||
- Update the warning message when the baseline lines of code count is unavailable. [#608](https://github.com/github/codeql-action/pull/608)
|
||||
|
||||
## 1.0.4 - 28 Jun 2021
|
||||
|
||||
- Fix `RUNNER_TEMP environment variable must be set` when using runner. [#594](https://github.com/github/codeql-action/pull/594)
|
||||
- Fix couting of lines of code for C# projects. [#586](https://github.com/github/codeql-action/pull/586)
|
||||
|
||||
## 1.0.3 - 23 Jun 2021
|
||||
|
||||
No user facing changes.
|
||||
|
||||
## 1.0.2 - 17 Jun 2021
|
||||
|
||||
- Fix out of memory in hash computation. [#550](https://github.com/github/codeql-action/pull/550)
|
||||
- Clean up logging during analyze results. [#557](https://github.com/github/codeql-action/pull/557)
|
||||
- Add `--finalize-dataset` to `database finalize` call, freeing up some disk space after database creation. [#558](https://github.com/github/codeql-action/pull/558)
|
||||
|
||||
## 1.0.1 - 07 Jun 2021
|
||||
|
||||
- Pass the `--sarif-group-rules-by-pack` argument to CodeQL CLI invocations that generate SARIF. This means the SARIF rule object for each query will now be found underneath its corresponding query pack in `runs[].tool.extensions`. [#546](https://github.com/github/codeql-action/pull/546)
|
||||
- Output the location of CodeQL databases created in the analyze step. [#543](https://github.com/github/codeql-action/pull/543)
|
||||
|
||||
## 1.0.0 - 31 May 2021
|
||||
|
||||
- Add this changelog file. [#507](https://github.com/github/codeql-action/pull/507)
|
||||
- Improve grouping of analysis logs. Add a new log group containing a summary of metrics and diagnostics, if they were produced by CodeQL builtin queries. [#515](https://github.com/github/codeql-action/pull/515)
|
||||
- Add metrics and diagnostics summaries from custom query suites to the analysis summary log group. [#532](https://github.com/github/codeql-action/pull/532)
|
||||
@@ -1 +0,0 @@
|
||||
**/* @github/codeql-action-reviewers
|
||||
@@ -12,7 +12,7 @@ Please note that this project is released with a [Contributor Code of Conduct][c
|
||||
|
||||
## Development and Testing
|
||||
|
||||
Before you start, ensure that you have a recent version of node (14 or higher) installed, along with a recent version of npm (7 or higher). You can see which version of node is used by the action in `init/action.yml`.
|
||||
Before you start, ensure that you have a recent version of node installed. You can see which version of node is used by the action in `init/action.yml`.
|
||||
|
||||
### Common tasks
|
||||
|
||||
@@ -22,18 +22,29 @@ Before you start, ensure that you have a recent version of node (14 or higher) i
|
||||
|
||||
This project also includes configuration to run tests from VSCode (with support for breakpoints) - open the test file you wish to run and choose "Debug AVA test file" from the Run menu in the Run panel.
|
||||
|
||||
You may want to run `tsc --watch` from the command line or inside of vscode in order to ensure build artifacts are up to date as you are working.
|
||||
|
||||
### Checking in compiled artifacts and `node_modules`
|
||||
|
||||
Because CodeQL Action users consume the code directly from this repository, and there can be no build step during an GitHub Actions run, this repository contains all compiled artifacts and node modules. There is a PR check that will fail if any of the compiled artifacts are not up to date. Compiled artifacts are stored in the `lib/` directory. For all day-to-day development purposes, this folder can be ignored.
|
||||
|
||||
Only run `npm install` if you are explicitly changing the set of dependencies in `package.json`. The `node_modules` directory should be up to date when you check out, but if for some reason, there is an inconsistency use `npm ci && npm run removeNPMAbsolutePaths` to ensure the directory is in a state consistent with the `package-lock.json`. Note that due to a macOS-specific dependency, this command should be run on a macOS machine. There is a PR check to ensure the consistency of the `node_modules` directory.
|
||||
|
||||
### Running the action
|
||||
|
||||
To see the effect of your changes and to test them, push your changes in a branch and then look at the [Actions output](https://github.com/github/codeql-action/actions) for that branch. You can also exercise the code locally by running the automated tests.
|
||||
|
||||
### Running the action locally
|
||||
|
||||
It is possible to run this action locally via [act](https://github.com/nektos/act) via the following steps:
|
||||
|
||||
1. Create a GitHub [Personal Access Token](https://github.com/settings/tokens) (PAT).
|
||||
1. Install [act](https://github.com/nektos/act) v0.2.10 or greater.
|
||||
1. Add a `.env` file in the root of the project you are running:
|
||||
|
||||
```bash
|
||||
CODEQL_LOCAL_RUN=true
|
||||
|
||||
# Optional, for better logging
|
||||
GITHUB_JOB=<ANY_JOB_NAME>
|
||||
```
|
||||
|
||||
1. Run `act -j codeql -s GITHUB_TOKEN=<PAT>`
|
||||
|
||||
Running locally will generate the CodeQL database and run all the queries, but it will avoid uploading and reporting results to GitHub. Note that this must be done on a repository that _consumes_ this action, not this repository. The use case is to debug failures of this action on specific repositories.
|
||||
|
||||
### Integration tests
|
||||
|
||||
As well as the unit tests (see _Common tasks_ above), there are integration tests, defined in `.github/workflows/integration-testing.yml`. These are run by a CI check. Depending on the change you’re making, you may want to add a test to this file or extend an existing one.
|
||||
|
||||
45
README.md
45
README.md
@@ -1,8 +1,6 @@
|
||||
# CodeQL Action
|
||||
|
||||
This action runs GitHub's industry-leading semantic code analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
||||
|
||||
For a list of recent changes, see the CodeQL Action's [changelog](CHANGELOG.md).
|
||||
This action runs GitHub's industry-leading static analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/github/codeql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
||||
|
||||
## License
|
||||
|
||||
@@ -24,16 +22,7 @@ on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
# ┌───────────── minute (0 - 59)
|
||||
# │ ┌───────────── hour (0 - 23)
|
||||
# │ │ ┌───────────── day of the month (1 - 31)
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
- cron: '30 1 * * 0'
|
||||
- cron: '0 0 * * 0'
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
@@ -43,6 +32,17 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# Must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head of the pull request.
|
||||
# Only include this option if you are running this workflow on pull requests.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
# Only include this step if you are running this workflow on pull requests.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
@@ -98,16 +98,7 @@ Use the `config-file` parameter of the `init` action to enable the configuration
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
```
|
||||
|
||||
The configuration file can be located in a different repository. This is useful if you want to share the same configuration across multiple repositories. If the configuration file is in a private repository you can also specify an `external-repository-token` option. This should be a personal access token that has read access to any repositories containing referenced config files and queries.
|
||||
|
||||
```yaml
|
||||
- uses: github/codeql-action/init@v1
|
||||
with:
|
||||
config-file: owner/repo/codeql-config.yml@branch
|
||||
external-repository-token: ${{ secrets.EXTERNAL_REPOSITORY_TOKEN }}
|
||||
```
|
||||
|
||||
For information on how to write a configuration file, see "[Using a custom configuration file](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#using-a-custom-configuration-file)."
|
||||
The configuration file must be located within the local repository. For information on how to write a configuration file, see "[Using a custom configuration file](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#using-a-custom-configuration-file)."
|
||||
|
||||
If you only want to customise the queries used, you can specify them in your workflow instead of creating a config file, using the `queries` property of the `init` action:
|
||||
|
||||
@@ -128,11 +119,3 @@ By default, this will override any queries specified in a config file. If you wi
|
||||
## Troubleshooting
|
||||
|
||||
Read about [troubleshooting code scanning](https://help.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning).
|
||||
|
||||
### Note on "missing analysis" message
|
||||
|
||||
The very first time code scanning is run and if it is on a pull request, you will probably get a message mentioning a "missing analysis". This is expected.
|
||||
|
||||
After code scanning has analyzed the code in a pull request, it needs to compare the analysis of the topic branch (the merge commit of the branch you used to create the pull request) with the analysis of the base branch (the branch into which you want to merge the pull request). This allows code scanning to compute which alerts are newly introduced by the pull request, which alerts were already present in the base branch, and whether any existing alerts are fixed by the changes in the pull request. Initially, if you use a pull request to add code scanning to a repository, the base branch has not yet been analyzed, so it's not possible to compute these details. In this case, when you click through from the results check on the pull request you will see the "Missing analysis for base commit SHA-HASH" message.
|
||||
|
||||
For more information and other causes of this message, see [Reasons for the "missing analysis" message](https://docs.github.com/en/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/setting-up-code-scanning-for-a-repository#reasons-for-the-missing-analysis-message)
|
||||
|
||||
@@ -13,10 +13,6 @@ inputs:
|
||||
description: Upload the SARIF file
|
||||
required: false
|
||||
default: "true"
|
||||
cleanup-level:
|
||||
description: "Level of cleanup to perform on CodeQL databases at the end of the analyze step. This should either be 'none' to skip cleanup, or be a valid argument for the --mode flag of the CodeQL CLI command 'codeql database cleanup' as documented at https://codeql.github.com/docs/codeql-cli/manual/database-cleanup"
|
||||
required: false
|
||||
default: "brutal"
|
||||
ram:
|
||||
description: Override the amount of memory in MB to be used by CodeQL. By default, almost all the memory of the machine is used.
|
||||
required: false
|
||||
@@ -24,31 +20,17 @@ inputs:
|
||||
description: Specify whether or not to add code snippets to the output sarif file.
|
||||
required: false
|
||||
default: "false"
|
||||
skip-queries:
|
||||
description: If this option is set, the CodeQL database will be built but no queries will be run on it. Thus, no results will be produced.
|
||||
required: false
|
||||
default: "false"
|
||||
threads:
|
||||
description: The number of threads to be used by CodeQL.
|
||||
required: false
|
||||
checkout_path:
|
||||
description: "The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file."
|
||||
description: "The path at which the analyzed repository was checked out. Used to relativeize any absolute paths in the uploaded SARIF file."
|
||||
required: false
|
||||
default: ${{ github.workspace }}
|
||||
category:
|
||||
description: String used by Code Scanning for matching the analyses
|
||||
required: false
|
||||
upload-database:
|
||||
description: Whether to upload the resulting CodeQL database
|
||||
required: false
|
||||
default: "true"
|
||||
token:
|
||||
default: ${{ github.token }}
|
||||
matrix:
|
||||
default: ${{ toJson(matrix) }}
|
||||
outputs:
|
||||
db-locations:
|
||||
description: A map from language to absolute path for each database created by CodeQL.
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: '../lib/analyze-action.js'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: 'CodeQL: Init'
|
||||
description: 'Set up CodeQL'
|
||||
description: 'Setup the CodeQL tracer'
|
||||
author: 'GitHub'
|
||||
inputs:
|
||||
tools:
|
||||
@@ -16,31 +16,13 @@ inputs:
|
||||
config-file:
|
||||
description: Path of the config file to use
|
||||
required: false
|
||||
db-location:
|
||||
description: Path where CodeQL databases should be created. If not specified, a temporary directory will be used.
|
||||
required: false
|
||||
queries:
|
||||
description: Comma-separated list of additional queries to run. By default, this overrides the same setting in a configuration file; prefix with "+" to use both sets of queries.
|
||||
required: false
|
||||
packs:
|
||||
description: >-
|
||||
[Experimental] Comma-separated list of packs to run. Reference a pack in the format `scope/name[@version]`. If `version` is not
|
||||
specified, then the latest version of the pack is used. By default, this overrides the same setting in a
|
||||
configuration file; prefix with "+" to use both sets of packs.
|
||||
|
||||
This input is only available in single-language analyses. To use packs in multi-language
|
||||
analyses, you must specify packs in the codeql-config.yml file.
|
||||
required: false
|
||||
external-repository-token:
|
||||
description: A token for fetching external config files and queries if they reside in a private repository.
|
||||
required: false
|
||||
setup-python-dependencies:
|
||||
description: Try to auto-install your python dependencies
|
||||
required: true
|
||||
default: 'true'
|
||||
outputs:
|
||||
codeql-path:
|
||||
description: The path of the CodeQL binary used for analysis
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: '../lib/init-action.js'
|
||||
|
||||
441
lib/actions-util.js
generated
441
lib/actions-util.js
generated
@@ -7,19 +7,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const sharedEnv = __importStar(require("./shared-environment"));
|
||||
const util_1 = require("./util");
|
||||
/**
|
||||
* The utils in this module are meant to be run inside of the action only.
|
||||
* Code paths from the runner should not enter this module.
|
||||
*/
|
||||
/**
|
||||
* Wrapper around core.getInput for inputs that always have a value.
|
||||
* Also see getOptionalInput.
|
||||
@@ -43,24 +35,35 @@ function getOptionalInput(name) {
|
||||
return value.length > 0 ? value : undefined;
|
||||
}
|
||||
exports.getOptionalInput = getOptionalInput;
|
||||
function getTemporaryDirectory() {
|
||||
const value = process.env["CODEQL_ACTION_TEMP"];
|
||||
return value !== undefined && value !== ""
|
||||
? value
|
||||
: util_1.getRequiredEnvParam("RUNNER_TEMP");
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*/
|
||||
function getRequiredEnvParam(paramName) {
|
||||
const value = process.env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
core.debug(`${paramName}=${value}`);
|
||||
return value;
|
||||
}
|
||||
exports.getTemporaryDirectory = getTemporaryDirectory;
|
||||
function getToolCacheDirectory() {
|
||||
const value = process.env["CODEQL_ACTION_TOOL_CACHE"];
|
||||
return value !== undefined && value !== ""
|
||||
? value
|
||||
: util_1.getRequiredEnvParam("RUNNER_TOOL_CACHE");
|
||||
exports.getRequiredEnvParam = getRequiredEnvParam;
|
||||
/**
|
||||
* Ensures all required environment variables are set in the context of a local run.
|
||||
*/
|
||||
function prepareLocalRunEnvironment() {
|
||||
if (!util_1.isLocalRun()) {
|
||||
return;
|
||||
}
|
||||
core.debug("Action is running locally.");
|
||||
if (!process.env.GITHUB_JOB) {
|
||||
core.exportVariable("GITHUB_JOB", "UNKNOWN-JOB");
|
||||
}
|
||||
}
|
||||
exports.getToolCacheDirectory = getToolCacheDirectory;
|
||||
exports.prepareLocalRunEnvironment = prepareLocalRunEnvironment;
|
||||
/**
|
||||
* Gets the SHA of the commit that is currently checked out.
|
||||
*/
|
||||
exports.getCommitOid = async function (ref = "HEAD") {
|
||||
async function getCommitOid() {
|
||||
// Try to use git to get the current commit SHA. If that fails then
|
||||
// log but otherwise silently fall back to using the SHA from the environment.
|
||||
// The only time these two values will differ is during analysis of a PR when
|
||||
@@ -70,7 +73,7 @@ exports.getCommitOid = async function (ref = "HEAD") {
|
||||
// reported on the merge commit.
|
||||
try {
|
||||
let commitOid = "";
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("git"), ["rev-parse", ref], {
|
||||
await new toolrunnner.ToolRunner("git", ["rev-parse", "HEAD"], {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
@@ -85,207 +88,18 @@ exports.getCommitOid = async function (ref = "HEAD") {
|
||||
}
|
||||
catch (e) {
|
||||
core.info(`Failed to call git to get current commit. Continuing with data from environment: ${e}`);
|
||||
return util_1.getRequiredEnvParam("GITHUB_SHA");
|
||||
return getRequiredEnvParam("GITHUB_SHA");
|
||||
}
|
||||
};
|
||||
function isObject(o) {
|
||||
return o !== null && typeof o === "object";
|
||||
}
|
||||
const GLOB_PATTERN = new RegExp("(\\*\\*?)");
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
}
|
||||
function patternToRegExp(value) {
|
||||
return new RegExp(`^${value
|
||||
.toString()
|
||||
.split(GLOB_PATTERN)
|
||||
.reduce(function (arr, cur) {
|
||||
if (cur === "**") {
|
||||
arr.push(".*?");
|
||||
}
|
||||
else if (cur === "*") {
|
||||
arr.push("[^/]*?");
|
||||
}
|
||||
else if (cur) {
|
||||
arr.push(escapeRegExp(cur));
|
||||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.join("")}$`);
|
||||
}
|
||||
// this function should return true if patternA is a superset of patternB
|
||||
// e.g: * is a superset of main-* but main-* is not a superset of *.
|
||||
function patternIsSuperset(patternA, patternB) {
|
||||
return patternToRegExp(patternA).test(patternB);
|
||||
}
|
||||
exports.patternIsSuperset = patternIsSuperset;
|
||||
function branchesToArray(branches) {
|
||||
if (typeof branches === "string") {
|
||||
return [branches];
|
||||
}
|
||||
if (Array.isArray(branches)) {
|
||||
if (branches.length === 0) {
|
||||
return "**";
|
||||
}
|
||||
return branches;
|
||||
}
|
||||
return "**";
|
||||
}
|
||||
function toCodedErrors(errors) {
|
||||
return Object.entries(errors).reduce((acc, [key, value]) => {
|
||||
acc[key] = { message: value, code: key };
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
// code to send back via status report
|
||||
// message to add as a warning annotation to the run
|
||||
exports.WorkflowErrors = toCodedErrors({
|
||||
MismatchedBranches: `Please make sure that every branch in on.pull_request is also in on.push so that Code Scanning can compare pull requests against the state of the base branch.`,
|
||||
MissingPushHook: `Please specify an on.push hook so that Code Scanning can compare pull requests against the state of the base branch.`,
|
||||
PathsSpecified: `Using on.push.paths can prevent Code Scanning annotating new alerts in your pull requests.`,
|
||||
PathsIgnoreSpecified: `Using on.push.paths-ignore can prevent Code Scanning annotating new alerts in your pull requests.`,
|
||||
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
|
||||
});
|
||||
function getWorkflowErrors(doc) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h;
|
||||
const errors = [];
|
||||
const jobName = process.env.GITHUB_JOB;
|
||||
if (jobName) {
|
||||
const job = (_b = (_a = doc) === null || _a === void 0 ? void 0 : _a.jobs) === null || _b === void 0 ? void 0 : _b[jobName];
|
||||
const steps = (_c = job) === null || _c === void 0 ? void 0 : _c.steps;
|
||||
if (Array.isArray(steps)) {
|
||||
for (const step of steps) {
|
||||
// this was advice that we used to give in the README
|
||||
// we actually want to run the analysis on the merge commit
|
||||
// to produce results that are more inline with expectations
|
||||
// (i.e: this is what will happen if you merge this PR)
|
||||
// and avoid some race conditions
|
||||
if (((_d = step) === null || _d === void 0 ? void 0 : _d.run) === "git checkout HEAD^2") {
|
||||
errors.push(exports.WorkflowErrors.CheckoutWrongHead);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let missingPush = false;
|
||||
if (doc.on === undefined) {
|
||||
// this is not a valid config
|
||||
}
|
||||
else if (typeof doc.on === "string") {
|
||||
if (doc.on === "pull_request") {
|
||||
missingPush = true;
|
||||
}
|
||||
}
|
||||
else if (Array.isArray(doc.on)) {
|
||||
const hasPush = doc.on.includes("push");
|
||||
const hasPullRequest = doc.on.includes("pull_request");
|
||||
if (hasPullRequest && !hasPush) {
|
||||
missingPush = true;
|
||||
}
|
||||
}
|
||||
else if (isObject(doc.on)) {
|
||||
const hasPush = Object.prototype.hasOwnProperty.call(doc.on, "push");
|
||||
const hasPullRequest = Object.prototype.hasOwnProperty.call(doc.on, "pull_request");
|
||||
if (!hasPush && hasPullRequest) {
|
||||
missingPush = true;
|
||||
}
|
||||
if (hasPush && hasPullRequest) {
|
||||
const paths = (_e = doc.on.push) === null || _e === void 0 ? void 0 : _e.paths;
|
||||
// if you specify paths or paths-ignore you can end up with commits that have no baseline
|
||||
// if they didn't change any files
|
||||
// currently we cannot go back through the history and find the most recent baseline
|
||||
if (Array.isArray(paths) && paths.length > 0) {
|
||||
errors.push(exports.WorkflowErrors.PathsSpecified);
|
||||
}
|
||||
const pathsIgnore = (_f = doc.on.push) === null || _f === void 0 ? void 0 : _f["paths-ignore"];
|
||||
if (Array.isArray(pathsIgnore) && pathsIgnore.length > 0) {
|
||||
errors.push(exports.WorkflowErrors.PathsIgnoreSpecified);
|
||||
}
|
||||
}
|
||||
// if doc.on.pull_request is null that means 'all branches'
|
||||
// if doc.on.pull_request is undefined that means 'off'
|
||||
// we only want to check for mismatched branches if pull_request is on.
|
||||
if (doc.on.pull_request !== undefined) {
|
||||
const push = branchesToArray((_g = doc.on.push) === null || _g === void 0 ? void 0 : _g.branches);
|
||||
if (push !== "**") {
|
||||
const pull_request = branchesToArray((_h = doc.on.pull_request) === null || _h === void 0 ? void 0 : _h.branches);
|
||||
if (pull_request !== "**") {
|
||||
const difference = pull_request.filter((value) => !push.some((o) => patternIsSuperset(o, value)));
|
||||
if (difference.length > 0) {
|
||||
// there are branches in pull_request that may not have a baseline
|
||||
// because we are not building them on push
|
||||
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
||||
}
|
||||
}
|
||||
else if (push.length > 0) {
|
||||
// push is set up to run on a subset of branches
|
||||
// and you could open a PR against a branch with no baseline
|
||||
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (missingPush) {
|
||||
errors.push(exports.WorkflowErrors.MissingPushHook);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
exports.getWorkflowErrors = getWorkflowErrors;
|
||||
async function validateWorkflow() {
|
||||
let workflow;
|
||||
try {
|
||||
workflow = await getWorkflow();
|
||||
}
|
||||
catch (e) {
|
||||
return `error: getWorkflow() failed: ${e.toString()}`;
|
||||
}
|
||||
let workflowErrors;
|
||||
try {
|
||||
workflowErrors = getWorkflowErrors(workflow);
|
||||
}
|
||||
catch (e) {
|
||||
return `error: getWorkflowErrors() failed: ${e.toString()}`;
|
||||
}
|
||||
if (workflowErrors.length > 0) {
|
||||
let message;
|
||||
try {
|
||||
message = formatWorkflowErrors(workflowErrors);
|
||||
}
|
||||
catch (e) {
|
||||
return `error: formatWorkflowErrors() failed: ${e.toString()}`;
|
||||
}
|
||||
core.warning(message);
|
||||
}
|
||||
return formatWorkflowCause(workflowErrors);
|
||||
}
|
||||
exports.validateWorkflow = validateWorkflow;
|
||||
function formatWorkflowErrors(errors) {
|
||||
const issuesWere = errors.length === 1 ? "issue was" : "issues were";
|
||||
const errorsList = errors.map((e) => e.message).join(" ");
|
||||
return `${errors.length} ${issuesWere} detected with this workflow: ${errorsList}`;
|
||||
}
|
||||
exports.formatWorkflowErrors = formatWorkflowErrors;
|
||||
function formatWorkflowCause(errors) {
|
||||
if (errors.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return errors.map((e) => e.code).join(",");
|
||||
}
|
||||
exports.formatWorkflowCause = formatWorkflowCause;
|
||||
async function getWorkflow() {
|
||||
const relativePath = await getWorkflowPath();
|
||||
const absolutePath = path.join(util_1.getRequiredEnvParam("GITHUB_WORKSPACE"), relativePath);
|
||||
return yaml.safeLoad(fs.readFileSync(absolutePath, "utf-8"));
|
||||
}
|
||||
exports.getWorkflow = getWorkflow;
|
||||
exports.getCommitOid = getCommitOid;
|
||||
/**
|
||||
* Get the path of the currently executing workflow.
|
||||
*/
|
||||
async function getWorkflowPath() {
|
||||
const repo_nwo = util_1.getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
|
||||
const repo_nwo = getRequiredEnvParam("GITHUB_REPOSITORY").split("/");
|
||||
const owner = repo_nwo[0];
|
||||
const repo = repo_nwo[1];
|
||||
const run_id = Number(util_1.getRequiredEnvParam("GITHUB_RUN_ID"));
|
||||
const run_id = Number(getRequiredEnvParam("GITHUB_RUN_ID"));
|
||||
const apiClient = api.getActionsApiClient();
|
||||
const runsResponse = await apiClient.request("GET /repos/:owner/:repo/actions/runs/:run_id", {
|
||||
owner,
|
||||
@@ -300,7 +114,7 @@ async function getWorkflowPath() {
|
||||
* Get the workflow run ID.
|
||||
*/
|
||||
function getWorkflowRunID() {
|
||||
const workflowRunID = parseInt(util_1.getRequiredEnvParam("GITHUB_RUN_ID"), 10);
|
||||
const workflowRunID = parseInt(getRequiredEnvParam("GITHUB_RUN_ID"), 10);
|
||||
if (Number.isNaN(workflowRunID)) {
|
||||
throw new Error("GITHUB_RUN_ID must define a non NaN workflow run ID");
|
||||
}
|
||||
@@ -308,7 +122,7 @@ function getWorkflowRunID() {
|
||||
}
|
||||
exports.getWorkflowRunID = getWorkflowRunID;
|
||||
/**
|
||||
* Get the analysis key parameter for the current job.
|
||||
* Get the analysis key paramter for the current job.
|
||||
*
|
||||
* This will combine the workflow path and current job name.
|
||||
* Computing this the first time requires making requests to
|
||||
@@ -321,66 +135,26 @@ async function getAnalysisKey() {
|
||||
return analysisKey;
|
||||
}
|
||||
const workflowPath = await getWorkflowPath();
|
||||
const jobName = util_1.getRequiredEnvParam("GITHUB_JOB");
|
||||
const jobName = getRequiredEnvParam("GITHUB_JOB");
|
||||
analysisKey = `${workflowPath}:${jobName}`;
|
||||
core.exportVariable(analysisKeyEnvVar, analysisKey);
|
||||
return analysisKey;
|
||||
}
|
||||
exports.getAnalysisKey = getAnalysisKey;
|
||||
async function getAutomationID() {
|
||||
const analysis_key = await getAnalysisKey();
|
||||
const environment = getRequiredInput("matrix");
|
||||
return computeAutomationID(analysis_key, environment);
|
||||
}
|
||||
exports.getAutomationID = getAutomationID;
|
||||
function computeAutomationID(analysis_key, environment) {
|
||||
let automationID = `${analysis_key}/`;
|
||||
// the id has to be deterministic so we sort the fields
|
||||
if (environment !== undefined && environment !== "null") {
|
||||
const environmentObject = JSON.parse(environment);
|
||||
for (const entry of Object.entries(environmentObject).sort()) {
|
||||
if (typeof entry[1] === "string") {
|
||||
automationID += `${entry[0]}:${entry[1]}/`;
|
||||
}
|
||||
else {
|
||||
// In code scanning we just handle the string values,
|
||||
// the rest get converted to the empty string
|
||||
automationID += `${entry[0]}:/`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return automationID;
|
||||
}
|
||||
exports.computeAutomationID = computeAutomationID;
|
||||
/**
|
||||
* Get the ref currently being analyzed.
|
||||
*/
|
||||
async function getRef() {
|
||||
function getRef() {
|
||||
// Will be in the form "refs/heads/master" on a push event
|
||||
// or in the form "refs/pull/N/merge" on a pull_request event
|
||||
const ref = util_1.getRequiredEnvParam("GITHUB_REF");
|
||||
const sha = util_1.getRequiredEnvParam("GITHUB_SHA");
|
||||
// For pull request refs we want to detect whether the workflow
|
||||
// has run `git checkout HEAD^2` to analyze the 'head' ref rather
|
||||
// than the 'merge' ref. If so, we want to convert the ref that
|
||||
// we report back.
|
||||
const ref = getRequiredEnvParam("GITHUB_REF");
|
||||
// For pull request refs we want to convert from the 'merge' ref
|
||||
// to the 'head' ref, as that is what we want to analyse.
|
||||
// There should have been some code earlier in the workflow to do
|
||||
// the checkout, but we have no way of verifying that here.
|
||||
const pull_ref_regex = /refs\/pull\/(\d+)\/merge/;
|
||||
if (!pull_ref_regex.test(ref)) {
|
||||
return ref;
|
||||
}
|
||||
const head = await exports.getCommitOid("HEAD");
|
||||
// in actions/checkout@v2 we can check if git rev-parse HEAD == GITHUB_SHA
|
||||
// in actions/checkout@v1 this may not be true as it checks out the repository
|
||||
// using GITHUB_REF. There is a subtle race condition where
|
||||
// git rev-parse GITHUB_REF != GITHUB_SHA, so we must check
|
||||
// git git-parse GITHUB_REF == git rev-parse HEAD instead.
|
||||
const hasChangedRef = sha !== head &&
|
||||
(await exports.getCommitOid(ref.replace(/^refs\/pull\//, "refs/remotes/pull/"))) !==
|
||||
head;
|
||||
if (hasChangedRef) {
|
||||
const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head");
|
||||
core.debug(`No longer on merge commit, rewriting ref from ${ref} to ${newRef}.`);
|
||||
return newRef;
|
||||
if (pull_ref_regex.test(ref)) {
|
||||
return ref.replace(pull_ref_regex, "refs/pull/$1/head");
|
||||
}
|
||||
else {
|
||||
return ref;
|
||||
@@ -398,7 +172,7 @@ exports.getRef = getRef;
|
||||
*/
|
||||
async function createStatusReportBase(actionName, status, actionStartedAt, cause, exception) {
|
||||
const commitOid = process.env["GITHUB_SHA"] || "";
|
||||
const ref = await getRef();
|
||||
const ref = getRef();
|
||||
const workflowRunIDStr = process.env["GITHUB_RUN_ID"];
|
||||
let workflowRunID = -1;
|
||||
if (workflowRunIDStr) {
|
||||
@@ -412,11 +186,6 @@ async function createStatusReportBase(actionName, status, actionStartedAt, cause
|
||||
workflowStartedAt = actionStartedAt.toISOString();
|
||||
core.exportVariable(sharedEnv.CODEQL_WORKFLOW_STARTED_AT, workflowStartedAt);
|
||||
}
|
||||
// If running locally then the GITHUB_ACTION_REF cannot be trusted as it may be for the previous action
|
||||
// See https://github.com/actions/runner/issues/803
|
||||
const actionRef = isRunningLocalAction()
|
||||
? undefined
|
||||
: process.env["GITHUB_ACTION_REF"];
|
||||
const statusReport = {
|
||||
workflow_run_id: workflowRunID,
|
||||
workflow_name: workflowName,
|
||||
@@ -425,7 +194,6 @@ async function createStatusReportBase(actionName, status, actionStartedAt, cause
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
action_name: actionName,
|
||||
action_ref: actionRef,
|
||||
action_oid: "unknown",
|
||||
started_at: workflowStartedAt,
|
||||
action_started_at: actionStartedAt.toISOString(),
|
||||
@@ -448,10 +216,6 @@ async function createStatusReportBase(actionName, status, actionStartedAt, cause
|
||||
return statusReport;
|
||||
}
|
||||
exports.createStatusReportBase = createStatusReportBase;
|
||||
const GENERIC_403_MSG = "The repo on which this action is running is not opted-in to CodeQL code scanning.";
|
||||
const GENERIC_404_MSG = "Not authorized to used the CodeQL code scanning feature on this repo.";
|
||||
const OUT_OF_DATE_MSG = "CodeQL Action is out-of-date. Please upgrade to the latest version of codeql-action.";
|
||||
const INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the code scanning endpoint. Please update to a compatible version of codeql-action.";
|
||||
/**
|
||||
* Send a status report to the code_scanning/analysis/status endpoint.
|
||||
*
|
||||
@@ -461,103 +225,42 @@ const INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the code sc
|
||||
*
|
||||
* Returns whether sending the status report was successful of not.
|
||||
*/
|
||||
async function sendStatusReport(statusReport) {
|
||||
async function sendStatusReport(statusReport, ignoreFailures) {
|
||||
if (getRequiredEnvParam("GITHUB_SERVER_URL") !== util_1.GITHUB_DOTCOM_URL) {
|
||||
core.debug("Not sending status report to GitHub Enterprise");
|
||||
return true;
|
||||
}
|
||||
if (util_1.isLocalRun()) {
|
||||
core.debug("Not sending status report because this is a local run");
|
||||
return true;
|
||||
}
|
||||
const statusReportJSON = JSON.stringify(statusReport);
|
||||
core.debug(`Sending status report: ${statusReportJSON}`);
|
||||
const nwo = util_1.getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||
const nwo = getRequiredEnvParam("GITHUB_REPOSITORY");
|
||||
const [owner, repo] = nwo.split("/");
|
||||
const client = api.getActionsApiClient();
|
||||
try {
|
||||
await client.request("PUT /repos/:owner/:repo/code-scanning/analysis/status", {
|
||||
owner,
|
||||
repo,
|
||||
data: statusReportJSON,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
if (util_1.isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
case 403:
|
||||
if (workflowIsTriggeredByPushEvent() && isDependabotActor()) {
|
||||
core.setFailed('Workflows triggered by Dependabot on the "push" event run with read-only access. ' +
|
||||
"Uploading Code Scanning results requires write access. " +
|
||||
'To use Code Scanning with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. ' +
|
||||
"See https://docs.github.com/en/code-security/secure-coding/configuring-code-scanning#scanning-on-push for more information on how to configure these events.");
|
||||
}
|
||||
else {
|
||||
core.setFailed(e.message || GENERIC_403_MSG);
|
||||
}
|
||||
return false;
|
||||
case 404:
|
||||
core.setFailed(GENERIC_404_MSG);
|
||||
return false;
|
||||
case 422:
|
||||
// schema incompatibility when reporting status
|
||||
// this means that this action version is no longer compatible with the API
|
||||
// we still want to continue as it is likely the analysis endpoint will work
|
||||
if (util_1.getRequiredEnvParam("GITHUB_SERVER_URL") !== util_1.GITHUB_DOTCOM_URL) {
|
||||
core.debug(INCOMPATIBLE_MSG);
|
||||
}
|
||||
else {
|
||||
core.debug(OUT_OF_DATE_MSG);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const statusResponse = await client.request("PUT /repos/:owner/:repo/code-scanning/analysis/status", {
|
||||
owner,
|
||||
repo,
|
||||
data: statusReportJSON,
|
||||
});
|
||||
if (!ignoreFailures) {
|
||||
// If the status report request fails with a 403 or a 404, then this is a deliberate
|
||||
// message from the endpoint that the SARIF upload can be expected to fail too,
|
||||
// so the action should fail to avoid wasting actions minutes.
|
||||
//
|
||||
// Other failure responses (or lack thereof) could be transitory and should not
|
||||
// cause the action to fail.
|
||||
if (statusResponse.status === 403) {
|
||||
core.setFailed("The repo on which this action is running is not opted-in to CodeQL code scanning.");
|
||||
return false;
|
||||
}
|
||||
if (statusResponse.status === 404) {
|
||||
core.setFailed("Not authorized to used the CodeQL code scanning feature on this repo.");
|
||||
return false;
|
||||
}
|
||||
// something else has gone wrong and the request/response will be logged by octokit
|
||||
// it's possible this is a transient error and we should continue scanning
|
||||
core.error("An unexpected error occurred when sending code scanning status report.");
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.sendStatusReport = sendStatusReport;
|
||||
// Was the workflow run triggered by a `push` event, for example as opposed to a `pull_request` event.
|
||||
function workflowIsTriggeredByPushEvent() {
|
||||
return process.env["GITHUB_EVENT_NAME"] === "push";
|
||||
}
|
||||
// Is dependabot the actor that triggered the current workflow run.
|
||||
function isDependabotActor() {
|
||||
return process.env["GITHUB_ACTOR"] === "dependabot[bot]";
|
||||
}
|
||||
// Is the current action executing a local copy (i.e. we're running a workflow on the codeql-action repo itself)
|
||||
// as opposed to running a remote action (i.e. when another repo references us)
|
||||
function isRunningLocalAction() {
|
||||
const relativeScriptPath = getRelativeScriptPath();
|
||||
return (relativeScriptPath.startsWith("..") || path.isAbsolute(relativeScriptPath));
|
||||
}
|
||||
exports.isRunningLocalAction = isRunningLocalAction;
|
||||
// Get the location where the action is running from.
|
||||
// This can be used to get the actions name or tell if we're running a local action.
|
||||
function getRelativeScriptPath() {
|
||||
const runnerTemp = util_1.getRequiredEnvParam("RUNNER_TEMP");
|
||||
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
|
||||
return path.relative(actionsDirectory, __filename);
|
||||
}
|
||||
exports.getRelativeScriptPath = getRelativeScriptPath;
|
||||
// Reads the contents of GITHUB_EVENT_PATH as a JSON object
|
||||
function getWorkflowEvent() {
|
||||
const eventJsonFile = util_1.getRequiredEnvParam("GITHUB_EVENT_PATH");
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8"));
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to read workflow event JSON from ${eventJsonFile}: ${e}`);
|
||||
}
|
||||
}
|
||||
// Is the version of the repository we are currently analyzing from the default branch,
|
||||
// or alternatively from another branch or a pull request.
|
||||
async function isAnalyzingDefaultBranch() {
|
||||
var _a, _b;
|
||||
// Get the current ref and trim and refs/heads/ prefix
|
||||
let currentRef = await getRef();
|
||||
currentRef = currentRef.startsWith("refs/heads/")
|
||||
? currentRef.substr("refs/heads/".length)
|
||||
: currentRef;
|
||||
const event = getWorkflowEvent();
|
||||
const defaultBranch = (_b = (_a = event) === null || _a === void 0 ? void 0 : _a.repository) === null || _b === void 0 ? void 0 : _b.default_branch;
|
||||
return currentRef === defaultBranch;
|
||||
}
|
||||
exports.isAnalyzingDefaultBranch = isAnalyzingDefaultBranch;
|
||||
//# sourceMappingURL=actions-util.js.map
|
||||
File diff suppressed because one or more lines are too long
438
lib/actions-util.test.js
generated
438
lib/actions-util.test.js
generated
@@ -1,431 +1,31 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const sinon_1 = __importDefault(require("sinon"));
|
||||
const actionsutil = __importStar(require("./actions-util"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util_1 = require("./util");
|
||||
function errorCodes(actual, expected) {
|
||||
return [actual.map(({ code }) => code), expected.map(({ code }) => code)];
|
||||
}
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
ava_1.default("getRef() throws on the empty string", async (t) => {
|
||||
ava_1.default("getRef() throws on the empty string", (t) => {
|
||||
process.env["GITHUB_REF"] = "";
|
||||
await t.throwsAsync(actionsutil.getRef);
|
||||
t.throws(actions_util_1.getRef);
|
||||
});
|
||||
ava_1.default("getRef() returns merge PR ref if GITHUB_SHA still checked out", async (t) => {
|
||||
const expectedRef = "refs/pull/1/merge";
|
||||
const currentSha = "a".repeat(40);
|
||||
process.env["GITHUB_REF"] = expectedRef;
|
||||
process.env["GITHUB_SHA"] = currentSha;
|
||||
const callback = sinon_1.default.stub(actionsutil, "getCommitOid");
|
||||
callback.withArgs("HEAD").resolves(currentSha);
|
||||
const actualRef = await actionsutil.getRef();
|
||||
t.deepEqual(actualRef, expectedRef);
|
||||
callback.restore();
|
||||
});
|
||||
ava_1.default("getRef() returns merge PR ref if GITHUB_REF still checked out but sha has changed (actions checkout@v1)", async (t) => {
|
||||
const expectedRef = "refs/pull/1/merge";
|
||||
process.env["GITHUB_REF"] = expectedRef;
|
||||
process.env["GITHUB_SHA"] = "b".repeat(40);
|
||||
const sha = "a".repeat(40);
|
||||
const callback = sinon_1.default.stub(actionsutil, "getCommitOid");
|
||||
callback.withArgs("refs/remotes/pull/1/merge").resolves(sha);
|
||||
callback.withArgs("HEAD").resolves(sha);
|
||||
const actualRef = await actionsutil.getRef();
|
||||
t.deepEqual(actualRef, expectedRef);
|
||||
callback.restore();
|
||||
});
|
||||
ava_1.default("getRef() returns head PR ref if GITHUB_REF no longer checked out", async (t) => {
|
||||
process.env["GITHUB_REF"] = "refs/pull/1/merge";
|
||||
process.env["GITHUB_SHA"] = "a".repeat(40);
|
||||
const callback = sinon_1.default.stub(actionsutil, "getCommitOid");
|
||||
callback.withArgs("refs/pull/1/merge").resolves("a".repeat(40));
|
||||
callback.withArgs("HEAD").resolves("b".repeat(40));
|
||||
const actualRef = await actionsutil.getRef();
|
||||
t.deepEqual(actualRef, "refs/pull/1/head");
|
||||
callback.restore();
|
||||
});
|
||||
ava_1.default("computeAutomationID()", async (t) => {
|
||||
let actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", '{"language": "javascript", "os": "linux"}');
|
||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/");
|
||||
// check the environment sorting
|
||||
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", '{"os": "linux", "language": "javascript"}');
|
||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/language:javascript/os:linux/");
|
||||
// check that an empty environment produces the right results
|
||||
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", "{}");
|
||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/");
|
||||
// check non string environment values
|
||||
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", '{"number": 1, "object": {"language": "javascript"}}');
|
||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/number:/object:/");
|
||||
// check undefined environment
|
||||
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", undefined);
|
||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/");
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on is empty", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({ on: {} });
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is an array missing pull_request", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({ on: ["push"] });
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is an array missing push", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({ on: ["pull_request"] });
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MissingPushHook]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is valid", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: ["push", "pull_request"],
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is a valid superset", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: ["push", "pull_request", "schedule"],
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push should not have a path", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["main"], paths: ["test/*"] },
|
||||
pull_request: { branches: ["main"] },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.PathsSpecified]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is a correct object", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: { push: { branches: ["main"] }, pull_request: { branches: ["main"] } },
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.pull_requests is a string", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: { push: { branches: ["main"] }, pull_request: { branches: "*" } },
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.pull_requests is a string and correct", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: { push: { branches: "*" }, pull_request: { branches: "*" } },
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is correct with empty objects", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is mismatched", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["main"] },
|
||||
pull_request: { branches: ["feature"] },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is not mismatched", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["main", "feature"] },
|
||||
pull_request: { branches: ["main"] },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push is mismatched for pull_request", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["main"] },
|
||||
pull_request: { branches: ["main", "feature"] },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() for a range of malformed workflows", (t) => {
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: 1,
|
||||
pull_request: 1,
|
||||
},
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: 1,
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: [1],
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { 1: 1 },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { test: 1 },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { test: [1] },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { test: { steps: 1 } },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { test: { steps: [{ notrun: "git checkout HEAD^2" }] } },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: 1,
|
||||
jobs: { test: [undefined] },
|
||||
}), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(1), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: {
|
||||
branches: 1,
|
||||
},
|
||||
pull_request: {
|
||||
branches: 1,
|
||||
},
|
||||
},
|
||||
}), []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.pull_request for every branch but push specifies branches", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.pull_request for wildcard branches", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["feature/*"] },
|
||||
pull_request: { branches: "feature/moose" },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.pull_request for mismatched wildcard branches", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: {
|
||||
push: { branches: ["feature/moose"] },
|
||||
pull_request: { branches: "feature/*" },
|
||||
},
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when HEAD^2 is checked out", (t) => {
|
||||
process.env.GITHUB_JOB = "test";
|
||||
const errors = actionsutil.getWorkflowErrors({
|
||||
on: ["push", "pull_request"],
|
||||
jobs: { test: { steps: [{ run: "git checkout HEAD^2" }] } },
|
||||
});
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.CheckoutWrongHead]));
|
||||
});
|
||||
ava_1.default("formatWorkflowErrors() when there is one error", (t) => {
|
||||
const message = actionsutil.formatWorkflowErrors([
|
||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
||||
]);
|
||||
t.true(message.startsWith("1 issue was detected with this workflow:"));
|
||||
});
|
||||
ava_1.default("formatWorkflowErrors() when there are multiple errors", (t) => {
|
||||
const message = actionsutil.formatWorkflowErrors([
|
||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
||||
actionsutil.WorkflowErrors.PathsSpecified,
|
||||
]);
|
||||
t.true(message.startsWith("2 issues were detected with this workflow:"));
|
||||
});
|
||||
ava_1.default("formatWorkflowCause() with no errors", (t) => {
|
||||
const message = actionsutil.formatWorkflowCause([]);
|
||||
t.deepEqual(message, undefined);
|
||||
});
|
||||
ava_1.default("formatWorkflowCause()", (t) => {
|
||||
const message = actionsutil.formatWorkflowCause([
|
||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
||||
actionsutil.WorkflowErrors.PathsSpecified,
|
||||
]);
|
||||
t.deepEqual(message, "CheckoutWrongHead,PathsSpecified");
|
||||
t.deepEqual(actionsutil.formatWorkflowCause([]), undefined);
|
||||
});
|
||||
ava_1.default("patternIsSuperset()", (t) => {
|
||||
t.false(actionsutil.patternIsSuperset("main-*", "main"));
|
||||
t.true(actionsutil.patternIsSuperset("*", "*"));
|
||||
t.true(actionsutil.patternIsSuperset("*", "main-*"));
|
||||
t.false(actionsutil.patternIsSuperset("main-*", "*"));
|
||||
t.false(actionsutil.patternIsSuperset("main-*", "main"));
|
||||
t.true(actionsutil.patternIsSuperset("main", "main"));
|
||||
t.false(actionsutil.patternIsSuperset("*", "feature/*"));
|
||||
t.true(actionsutil.patternIsSuperset("**", "feature/*"));
|
||||
t.false(actionsutil.patternIsSuperset("feature-*", "**"));
|
||||
t.false(actionsutil.patternIsSuperset("a/**/c", "a/**/d"));
|
||||
t.false(actionsutil.patternIsSuperset("a/**/c", "a/**"));
|
||||
t.true(actionsutil.patternIsSuperset("a/**", "a/**/c"));
|
||||
t.true(actionsutil.patternIsSuperset("a/**/c", "a/main-**/c"));
|
||||
t.false(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/d/**/c"));
|
||||
t.true(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/b/c/**/c"));
|
||||
t.true(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/b/d/**/c"));
|
||||
t.false(actionsutil.patternIsSuperset("a/**/c/d/**/c", "a/**/b/**/c"));
|
||||
t.false(actionsutil.patternIsSuperset("a/main-**/c", "a/**/c"));
|
||||
t.true(actionsutil.patternIsSuperset("/robin/*/release/*", "/robin/moose/release/goose"));
|
||||
t.false(actionsutil.patternIsSuperset("/robin/moose/release/goose", "/robin/*/release/*"));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when branches contain dots", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
on:
|
||||
push:
|
||||
branches: [4.1, master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [4.1, master]
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on.push has a trailing comma", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [master, ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() should only report the current job's CheckoutWrongHead", (t) => {
|
||||
process.env.GITHUB_JOB = "test";
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
jobs:
|
||||
test:
|
||||
steps:
|
||||
- run: "git checkout HEAD^2"
|
||||
|
||||
test2:
|
||||
steps:
|
||||
- run: "git checkout HEAD^2"
|
||||
|
||||
test3:
|
||||
steps: []
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.CheckoutWrongHead]));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() should not report a different job's CheckoutWrongHead", (t) => {
|
||||
process.env.GITHUB_JOB = "test3";
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
jobs:
|
||||
test:
|
||||
steps:
|
||||
- run: "git checkout HEAD^2"
|
||||
|
||||
test2:
|
||||
steps:
|
||||
- run: "git checkout HEAD^2"
|
||||
|
||||
test3:
|
||||
steps: []
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() when on is missing", (t) => {
|
||||
const errors = actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
`));
|
||||
t.deepEqual(...errorCodes(errors, []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() with a different on setup", (t) => {
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on: "workflow_dispatch"
|
||||
`)), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on: [workflow_dispatch]
|
||||
`)), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
`)), []));
|
||||
});
|
||||
ava_1.default("getWorkflowErrors() should not report an error if PRs are totally unconfigured", (t) => {
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
`)), []));
|
||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.safeLoad(`
|
||||
name: "CodeQL"
|
||||
on: ["push"]
|
||||
`)), []));
|
||||
});
|
||||
ava_1.default("initializeEnvironment", (t) => {
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
|
||||
t.deepEqual(util_1.getMode(), util_1.Mode.actions);
|
||||
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "1.2.3");
|
||||
util_1.initializeEnvironment(util_1.Mode.runner, "4.5.6");
|
||||
t.deepEqual(util_1.getMode(), util_1.Mode.runner);
|
||||
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "4.5.6");
|
||||
});
|
||||
ava_1.default("isAnalyzingDefaultBranch()", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
const envFile = path.join(tmpDir, "event.json");
|
||||
fs.writeFileSync(envFile, JSON.stringify({
|
||||
repository: {
|
||||
default_branch: "main",
|
||||
},
|
||||
}));
|
||||
process.env["GITHUB_EVENT_PATH"] = envFile;
|
||||
process.env["GITHUB_REF"] = "main";
|
||||
process.env["GITHUB_SHA"] = "1234";
|
||||
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), true);
|
||||
process.env["GITHUB_REF"] = "refs/heads/main";
|
||||
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), true);
|
||||
process.env["GITHUB_REF"] = "feature";
|
||||
t.deepEqual(await actionsutil.isAnalyzingDefaultBranch(), false);
|
||||
});
|
||||
ava_1.default("prepareEnvironment() when a local run", (t) => {
|
||||
const origLocalRun = process.env.CODEQL_LOCAL_RUN;
|
||||
process.env.CODEQL_LOCAL_RUN = "false";
|
||||
process.env.GITHUB_JOB = "YYY";
|
||||
actions_util_1.prepareLocalRunEnvironment();
|
||||
// unchanged
|
||||
t.deepEqual(process.env.GITHUB_JOB, "YYY");
|
||||
process.env.CODEQL_LOCAL_RUN = "true";
|
||||
actions_util_1.prepareLocalRunEnvironment();
|
||||
// unchanged
|
||||
t.deepEqual(process.env.GITHUB_JOB, "YYY");
|
||||
process.env.GITHUB_JOB = "";
|
||||
actions_util_1.prepareLocalRunEnvironment();
|
||||
// updated
|
||||
t.deepEqual(process.env.GITHUB_JOB, "UNKNOWN-JOB");
|
||||
process.env.CODEQL_LOCAL_RUN = origLocalRun;
|
||||
});
|
||||
//# sourceMappingURL=actions-util.test.js.map
|
||||
File diff suppressed because one or more lines are too long
28
lib/analysis-paths.js
generated
28
lib/analysis-paths.js
generated
@@ -1,18 +1,10 @@
|
||||
"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 path = __importStar(require("path"));
|
||||
function isInterpretedLanguage(language) {
|
||||
return (language === "javascript" || language === "python" || language === "ruby");
|
||||
return language === "javascript" || language === "python";
|
||||
}
|
||||
// Matches a string containing only characters that are legal to include in paths on windows.
|
||||
exports.legalWindowsPathCharactersRegex = /^[^<>:"|?]*$/;
|
||||
exports.legalWindowsPathCharactersRegex = /^[^<>:"\|?]*$/;
|
||||
// Builds an environment variable suitable for LGTM_INDEX_INCLUDE or LGTM_INDEX_EXCLUDE
|
||||
function buildIncludeExcludeEnvVar(paths) {
|
||||
// Ignore anything containing a *
|
||||
@@ -28,7 +20,7 @@ function printPathFiltersWarning(config, logger) {
|
||||
// If any other languages are detected/configured then show a warning.
|
||||
if ((config.paths.length !== 0 || config.pathsIgnore.length !== 0) &&
|
||||
!config.languages.every(isInterpretedLanguage)) {
|
||||
logger.warning('The "paths"/"paths-ignore" fields of the config only have effect for JavaScript and Python');
|
||||
logger.warning('The "paths"/"paths-ignore" fields of the config only have effect for Javascript and Python');
|
||||
}
|
||||
}
|
||||
exports.printPathFiltersWarning = printPathFiltersWarning;
|
||||
@@ -43,18 +35,8 @@ function includeAndExcludeAnalysisPaths(config) {
|
||||
if (config.paths.length !== 0) {
|
||||
process.env["LGTM_INDEX_INCLUDE"] = buildIncludeExcludeEnvVar(config.paths);
|
||||
}
|
||||
// If the temporary or tools directory is in the working directory ignore that too.
|
||||
const tempRelativeToWorking = path.relative(process.cwd(), config.tempDir);
|
||||
const toolsRelativeToWorking = path.relative(process.cwd(), config.toolCacheDir);
|
||||
let pathsIgnore = config.pathsIgnore;
|
||||
if (!tempRelativeToWorking.startsWith("..")) {
|
||||
pathsIgnore = pathsIgnore.concat(tempRelativeToWorking);
|
||||
}
|
||||
if (!toolsRelativeToWorking.startsWith("..")) {
|
||||
pathsIgnore = pathsIgnore.concat(toolsRelativeToWorking);
|
||||
}
|
||||
if (pathsIgnore.length !== 0) {
|
||||
process.env["LGTM_INDEX_EXCLUDE"] = buildIncludeExcludeEnvVar(pathsIgnore);
|
||||
if (config.pathsIgnore.length !== 0) {
|
||||
process.env["LGTM_INDEX_EXCLUDE"] = buildIncludeExcludeEnvVar(config.pathsIgnore);
|
||||
}
|
||||
// The 'LGTM_INDEX_FILTERS' environment variable controls which files are
|
||||
// extracted or ignored. It does not control which directories are traversed.
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"analysis-paths.js","sourceRoot":"","sources":["../src/analysis-paths.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"analysis-paths.js","sourceRoot":"","sources":["../src/analysis-paths.ts"],"names":[],"mappings":";;AAGA,SAAS,qBAAqB,CAAC,QAAQ;IACrC,OAAO,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,QAAQ,CAAC;AAC5D,CAAC;AAED,6FAA6F;AAChF,QAAA,+BAA+B,GAAG,eAAe,CAAC;AAE/D,uFAAuF;AACvF,SAAS,yBAAyB,CAAC,KAAe;IAChD,iCAAiC;IACjC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnD,uDAAuD;IACvD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;QAChC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,uCAA+B,CAAC,CAAC,CAAC;KACvE;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,uBAAuB,CACrC,MAA0B,EAC1B,MAAc;IAEd,oEAAoE;IACpE,sEAAsE;IACtE,IACE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC;QAC9D,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAC9C;QACA,MAAM,CAAC,OAAO,CACZ,4FAA4F,CAC7F,CAAC;KACH;AACH,CAAC;AAdD,0DAcC;AAED,SAAgB,8BAA8B,CAAC,MAA0B;IACvE,0EAA0E;IAC1E,+DAA+D;IAC/D,sEAAsE;IACtE,qDAAqD;IACrD,gFAAgF;IAChF,sEAAsE;IACtE,sDAAsD;IACtD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;KAC7E;IACD,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QACnC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,yBAAyB,CAC3D,MAAM,CAAC,WAAW,CACnB,CAAC;KACH;IAED,yEAAyE;IACzE,6EAA6E;IAC7E,wDAAwD;IACxD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACxD;AACH,CAAC;AA1BD,wEA0BC"}
|
||||
35
lib/analysis-paths.test.js
generated
35
lib/analysis-paths.test.js
generated
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
@@ -6,11 +9,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const analysisPaths = __importStar(require("./analysis-paths"));
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
@@ -27,9 +26,6 @@ ava_1.default("emptyPaths", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
packs: {},
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||
@@ -48,9 +44,6 @@ ava_1.default("nonEmptyPaths", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
packs: {},
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
||||
@@ -58,26 +51,4 @@ ava_1.default("nonEmptyPaths", async (t) => {
|
||||
t.is(process.env["LGTM_INDEX_FILTERS"], "include:path1\ninclude:path2\ninclude:**/path3\nexclude:path4\nexclude:path5\nexclude:path6/**");
|
||||
});
|
||||
});
|
||||
ava_1.default("exclude temp dir", async (t) => {
|
||||
return await util.withTmpDir(async (toolCacheDir) => {
|
||||
const tempDir = path.join(process.cwd(), "codeql-runner-temp");
|
||||
const config = {
|
||||
languages: [],
|
||||
queries: {},
|
||||
pathsIgnore: [],
|
||||
paths: [],
|
||||
originalUserInput: {},
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: "",
|
||||
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
|
||||
dbLocation: path.resolve(tempDir, "codeql_databases"),
|
||||
packs: {},
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||
t.is(process.env["LGTM_INDEX_EXCLUDE"], "codeql-runner-temp");
|
||||
t.is(process.env["LGTM_INDEX_FILTERS"], undefined);
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=analysis-paths.test.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA6B;AAE7B,8CAAuB;AAEvB,gEAAkD;AAClD,mDAA6C;AAC7C,6CAA+B;AAE/B,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,aAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YAC3C,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO;YACP,YAAY;YACZ,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC;YACrD,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9D,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
||||
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAuB;AAEvB,gEAAkD;AAClD,mDAA6C;AAC7C,6CAA+B;AAE/B,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,aAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;SACd,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YAC3C,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;SACd,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
||||
98
lib/analyze-action.js
generated
98
lib/analyze-action.js
generated
@@ -7,19 +7,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const analyze_1 = require("./analyze");
|
||||
const config_utils_1 = require("./config-utils");
|
||||
const database_upload_1 = require("./database-upload");
|
||||
const logging_1 = require("./logging");
|
||||
const repository_1 = require("./repository");
|
||||
const upload_lib = __importStar(require("./upload-lib"));
|
||||
const util = __importStar(require("./util"));
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
async function sendStatusReport(startedAt, stats, error) {
|
||||
var _a, _b, _c;
|
||||
const status = ((_a = stats) === null || _a === void 0 ? void 0 : _a.analyze_failure_language) !== undefined || error !== undefined
|
||||
@@ -34,99 +28,29 @@ async function sendStatusReport(startedAt, stats, error) {
|
||||
}
|
||||
async function run() {
|
||||
const startedAt = new Date();
|
||||
let uploadStats = undefined;
|
||||
let runStats = undefined;
|
||||
let config = undefined;
|
||||
util.initializeEnvironment(util.Mode.actions, pkg.version);
|
||||
let stats = undefined;
|
||||
try {
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("finish", "starting", startedAt)))) {
|
||||
actionsUtil.prepareLocalRunEnvironment();
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("finish", "starting", startedAt), true))) {
|
||||
return;
|
||||
}
|
||||
const logger = logging_1.getActionsLogger();
|
||||
config = await config_utils_1.getConfig(actionsUtil.getTemporaryDirectory(), logger);
|
||||
const config = await config_utils_1.getConfig(actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), logger);
|
||||
if (config === undefined) {
|
||||
throw new Error("Config file could not be found at expected location. Has the 'init' action been called?");
|
||||
}
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
url: util.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
const outputDir = actionsUtil.getRequiredInput("output");
|
||||
const threads = util.getThreadsFlag(actionsUtil.getOptionalInput("threads"), logger);
|
||||
await analyze_1.runFinalize(outputDir, threads, config, logger);
|
||||
if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
|
||||
runStats = await analyze_1.runQueries(outputDir, util.getMemoryFlag(actionsUtil.getOptionalInput("ram")), util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")), threads, actionsUtil.getOptionalInput("category"), config, logger);
|
||||
}
|
||||
if (actionsUtil.getOptionalInput("cleanup-level") !== "none") {
|
||||
await analyze_1.runCleanup(config, actionsUtil.getOptionalInput("cleanup-level") || "brutal", logger);
|
||||
}
|
||||
const dbLocations = {};
|
||||
for (const language of config.languages) {
|
||||
dbLocations[language] = util.getCodeQLDatabasePath(config, language);
|
||||
}
|
||||
core.setOutput("db-locations", dbLocations);
|
||||
if (runStats && actionsUtil.getRequiredInput("upload") === "true") {
|
||||
uploadStats = await upload_lib.uploadFromActions(outputDir, config.gitHubVersion, apiDetails, logger);
|
||||
}
|
||||
else {
|
||||
logger.info("Not uploading results");
|
||||
}
|
||||
const repositoryNwo = repository_1.parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY"));
|
||||
await database_upload_1.uploadDatabases(repositoryNwo, config, apiDetails, logger);
|
||||
stats = await analyze_1.runAnalyze(repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(), actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), actionsUtil.getRequiredInput("upload") === "true", "actions", actionsUtil.getRequiredInput("output"), util.getMemoryFlag(actionsUtil.getOptionalInput("ram")), util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")), util.getThreadsFlag(actionsUtil.getOptionalInput("threads"), logger), config, logger);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
console.log(error);
|
||||
if (error instanceof analyze_1.CodeQLAnalysisError) {
|
||||
const stats = { ...error.queriesStatusReport };
|
||||
await sendStatusReport(startedAt, stats, error);
|
||||
}
|
||||
else {
|
||||
await sendStatusReport(startedAt, undefined, error);
|
||||
}
|
||||
await sendStatusReport(startedAt, stats, error);
|
||||
return;
|
||||
}
|
||||
finally {
|
||||
if (core.isDebug() && config !== undefined) {
|
||||
core.info("Debug mode is on. Printing CodeQL debug logs...");
|
||||
for (const language of config.languages) {
|
||||
const databaseDirectory = util.getCodeQLDatabasePath(config, language);
|
||||
const logsDirectory = path.join(databaseDirectory, "log");
|
||||
const walkLogFiles = (dir) => {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile()) {
|
||||
core.startGroup(`CodeQL Debug Logs - ${language} - ${entry.name}`);
|
||||
process.stdout.write(fs.readFileSync(path.resolve(dir, entry.name)));
|
||||
core.endGroup();
|
||||
}
|
||||
else if (entry.isDirectory()) {
|
||||
walkLogFiles(path.resolve(dir, entry.name));
|
||||
}
|
||||
}
|
||||
};
|
||||
walkLogFiles(logsDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (runStats && uploadStats) {
|
||||
await sendStatusReport(startedAt, { ...runStats, ...uploadStats });
|
||||
}
|
||||
else if (runStats) {
|
||||
await sendStatusReport(startedAt, { ...runStats });
|
||||
}
|
||||
else {
|
||||
await sendStatusReport(startedAt, undefined);
|
||||
}
|
||||
await sendStatusReport(startedAt, stats);
|
||||
}
|
||||
async function runWrapper() {
|
||||
try {
|
||||
await run();
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`analyze action failed: ${error}`);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
void runWrapper();
|
||||
run().catch((e) => {
|
||||
core.setFailed(`analyze action failed: ${e}`);
|
||||
console.log(e);
|
||||
});
|
||||
//# sourceMappingURL=analyze-action.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"analyze-action.js","sourceRoot":"","sources":["../src/analyze-action.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"analyze-action.js","sourceRoot":"","sources":["../src/analyze-action.ts"],"names":[],"mappings":"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"}
|
||||
213
lib/analyze.js
generated
213
lib/analyze.js
generated
@@ -7,24 +7,15 @@ 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 toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const analysisPaths = __importStar(require("./analysis-paths"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const count_loc_1 = require("./count-loc");
|
||||
const languages_1 = require("./languages");
|
||||
const sharedEnv = __importStar(require("./shared-environment"));
|
||||
const upload_lib = __importStar(require("./upload-lib"));
|
||||
const util = __importStar(require("./util"));
|
||||
class CodeQLAnalysisError extends Error {
|
||||
constructor(queriesStatusReport, message) {
|
||||
super(message);
|
||||
this.name = "CodeQLAnalysisError";
|
||||
this.queriesStatusReport = queriesStatusReport;
|
||||
}
|
||||
}
|
||||
exports.CodeQLAnalysisError = CodeQLAnalysisError;
|
||||
async function setupPythonExtractor(logger) {
|
||||
const codeqlPython = process.env["CODEQL_PYTHON"];
|
||||
if (codeqlPython === undefined || codeqlPython.length === 0) {
|
||||
@@ -39,14 +30,14 @@ async function setupPythonExtractor(logger) {
|
||||
},
|
||||
},
|
||||
};
|
||||
await new toolrunner.ToolRunner(codeqlPython, [
|
||||
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 toolrunner.ToolRunner(codeqlPython, ["-c", "import sys; print(sys.version_info[0])"], options).exec();
|
||||
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;
|
||||
}
|
||||
@@ -56,193 +47,83 @@ async function createdDBForScannedLanguages(config, logger) {
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
for (const language of config.languages) {
|
||||
if (languages_1.isScannedLanguage(language) &&
|
||||
!dbIsFinalized(config, language, logger)) {
|
||||
if (languages_1.isScannedLanguage(language)) {
|
||||
logger.startGroup(`Extracting ${language}`);
|
||||
if (language === languages_1.Language.python) {
|
||||
await setupPythonExtractor(logger);
|
||||
}
|
||||
await codeql.extractScannedLanguage(util.getCodeQLDatabasePath(config, language), language);
|
||||
await codeql.extractScannedLanguage(util.getCodeQLDatabasePath(config.tempDir, language), language);
|
||||
logger.endGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
function dbIsFinalized(config, language, logger) {
|
||||
const dbPath = util.getCodeQLDatabasePath(config, language);
|
||||
try {
|
||||
const dbInfo = yaml.load(fs.readFileSync(path.resolve(dbPath, "codeql-database.yml"), "utf8"));
|
||||
return !("inProgress" in dbInfo);
|
||||
}
|
||||
catch (e) {
|
||||
logger.warning(`Could not check whether database for ${language} was finalized. Assuming it is not.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function finalizeDatabaseCreation(config, threadsFlag, logger) {
|
||||
async function finalizeDatabaseCreation(config, logger) {
|
||||
await createdDBForScannedLanguages(config, logger);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
for (const language of config.languages) {
|
||||
if (dbIsFinalized(config, language, logger)) {
|
||||
logger.info(`There is already a finalized database for ${language} at the location where the CodeQL Action places databases, so we did not create one.`);
|
||||
}
|
||||
else {
|
||||
logger.startGroup(`Finalizing ${language}`);
|
||||
await codeql.finalizeDatabase(util.getCodeQLDatabasePath(config, language), threadsFlag);
|
||||
logger.endGroup();
|
||||
}
|
||||
logger.startGroup(`Finalizing ${language}`);
|
||||
await codeql.finalizeDatabase(util.getCodeQLDatabasePath(config.tempDir, language));
|
||||
logger.endGroup();
|
||||
}
|
||||
}
|
||||
// Runs queries and creates sarif files in the given folder
|
||||
async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, automationDetailsId, config, logger) {
|
||||
var _a, _b;
|
||||
async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, config, logger) {
|
||||
const statusReport = {};
|
||||
// count the number of lines in the background
|
||||
const locPromise = count_loc_1.countLoc(path.resolve(),
|
||||
// config.paths specifies external directories. the current
|
||||
// directory is included in the analysis by default. Replicate
|
||||
// that here.
|
||||
config.paths, config.pathsIgnore, config.languages, logger);
|
||||
for (const language of config.languages) {
|
||||
logger.startGroup(`Analyzing ${language}`);
|
||||
const queries = config.queries[language];
|
||||
const packsWithVersion = config.packs[language] || [];
|
||||
const hasBuiltinQueries = ((_a = queries) === null || _a === void 0 ? void 0 : _a.builtin.length) > 0;
|
||||
const hasCustomQueries = ((_b = queries) === null || _b === void 0 ? void 0 : _b.custom.length) > 0;
|
||||
const hasPackWithCustomQueries = packsWithVersion.length > 0;
|
||||
if (!hasBuiltinQueries && !hasCustomQueries && !hasPackWithCustomQueries) {
|
||||
if (queries.builtin.length === 0 && queries.custom.length === 0) {
|
||||
throw new Error(`Unable to analyse ${language} as no queries were selected for this language`);
|
||||
}
|
||||
try {
|
||||
if (hasPackWithCustomQueries) {
|
||||
logger.info("*************");
|
||||
logger.info("Performing analysis with custom QL Packs. QL Packs are an experimental feature.");
|
||||
logger.info("And should not be used in production yet.");
|
||||
logger.info("*************");
|
||||
logger.startGroup(`Downloading custom packs for ${language}`);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
const results = await codeql.packDownload(packsWithVersion);
|
||||
logger.info(`Downloaded packs: ${results.packs
|
||||
.map((r) => `${r.name}@${r.version || "latest"}`)
|
||||
.join(", ")}`);
|
||||
logger.endGroup();
|
||||
}
|
||||
logger.startGroup(`Running queries for ${language}`);
|
||||
const querySuitePaths = [];
|
||||
if (queries["builtin"].length > 0) {
|
||||
const startTimeBuiltIn = new Date().getTime();
|
||||
querySuitePaths.push(await runQueryGroup(language, "builtin", createQuerySuiteContents(queries["builtin"]), undefined));
|
||||
statusReport[`analyze_builtin_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeBuiltIn;
|
||||
}
|
||||
const startTimeCustom = new Date().getTime();
|
||||
let ranCustom = false;
|
||||
for (let i = 0; i < queries["custom"].length; ++i) {
|
||||
if (queries["custom"][i].queries.length > 0) {
|
||||
querySuitePaths.push(await runQueryGroup(language, `custom-${i}`, createQuerySuiteContents(queries["custom"][i].queries), queries["custom"][i].searchPath));
|
||||
ranCustom = true;
|
||||
for (const type of ["builtin", "custom"]) {
|
||||
if (queries[type].length > 0) {
|
||||
const startTime = new Date().getTime();
|
||||
const databasePath = util.getCodeQLDatabasePath(config.tempDir, language);
|
||||
// Pass the queries to codeql using a file instead of using the command
|
||||
// line to avoid command line length restrictions, particularly on windows.
|
||||
const querySuitePath = `${databasePath}-queries-${type}.qls`;
|
||||
const querySuiteContents = queries[type]
|
||||
.map((q) => `- query: ${q}`)
|
||||
.join("\n");
|
||||
fs.writeFileSync(querySuitePath, querySuiteContents);
|
||||
logger.debug(`Query suite file for ${language}...\n${querySuiteContents}`);
|
||||
const sarifFile = path.join(sarifFolder, `${language}-${type}.sarif`);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
await codeql.databaseAnalyze(databasePath, sarifFile, querySuitePath, memoryFlag, addSnippetsFlag, threadsFlag);
|
||||
logger.debug(`SARIF results for database ${language} created at "${sarifFile}"`);
|
||||
logger.endGroup();
|
||||
// Record the performance
|
||||
const endTime = new Date().getTime();
|
||||
statusReport[`analyze_${type}_queries_${language}_duration_ms`] =
|
||||
endTime - startTime;
|
||||
}
|
||||
}
|
||||
if (packsWithVersion.length > 0) {
|
||||
querySuitePaths.push(await runQueryGroup(language, "packs", createPackSuiteContents(packsWithVersion), undefined));
|
||||
ranCustom = true;
|
||||
}
|
||||
if (ranCustom) {
|
||||
statusReport[`analyze_custom_queries_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeCustom;
|
||||
}
|
||||
logger.endGroup();
|
||||
logger.startGroup(`Interpreting results for ${language}`);
|
||||
const startTimeInterpretResults = new Date().getTime();
|
||||
const sarifFile = path.join(sarifFolder, `${language}.sarif`);
|
||||
const analysisSummary = await runInterpretResults(language, querySuitePaths, sarifFile);
|
||||
await injectLinesOfCode(sarifFile, language, locPromise);
|
||||
statusReport[`interpret_results_${language}_duration_ms`] =
|
||||
new Date().getTime() - startTimeInterpretResults;
|
||||
logger.endGroup();
|
||||
logger.info(analysisSummary);
|
||||
printLinesOfCodeSummary(logger, language, await locPromise);
|
||||
}
|
||||
catch (e) {
|
||||
logger.error(`Error running analysis for ${language}: ${e}`);
|
||||
logger.info(e);
|
||||
logger.info(e.stack);
|
||||
statusReport.analyze_failure_language = language;
|
||||
throw new CodeQLAnalysisError(statusReport, `Error running analysis for ${language}: ${e}`);
|
||||
return statusReport;
|
||||
}
|
||||
}
|
||||
return statusReport;
|
||||
async function runInterpretResults(language, queries, sarifFile) {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
return await codeql.databaseInterpretResults(databasePath, queries, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId);
|
||||
}
|
||||
async function runQueryGroup(language, type, querySuiteContents, searchPath) {
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
// Pass the queries to codeql using a file instead of using the command
|
||||
// line to avoid command line length restrictions, particularly on windows.
|
||||
const querySuitePath = `${databasePath}-queries-${type}.qls`;
|
||||
fs.writeFileSync(querySuitePath, querySuiteContents);
|
||||
logger.debug(`Query suite file for ${language}-${type}...\n${querySuiteContents}`);
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
await codeql.databaseRunQueries(databasePath, searchPath, querySuitePath, memoryFlag, threadsFlag);
|
||||
logger.debug(`BQRS results produced for ${language} (queries: ${type})"`);
|
||||
return querySuitePath;
|
||||
}
|
||||
}
|
||||
exports.runQueries = runQueries;
|
||||
function createQuerySuiteContents(queries) {
|
||||
return queries.map((q) => `- query: ${q}`).join("\n");
|
||||
}
|
||||
function createPackSuiteContents(packsWithVersion) {
|
||||
return packsWithVersion.map(packWithVersionToQuerySuiteEntry).join("\n");
|
||||
}
|
||||
function packWithVersionToQuerySuiteEntry(pack) {
|
||||
let text = `- qlpack: ${pack.packName}`;
|
||||
if (pack.version) {
|
||||
text += `\n version: ${pack.version}`;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
async function runFinalize(outputDir, threadsFlag, config, logger) {
|
||||
async function runAnalyze(repositoryNwo, commitOid, ref, analysisKey, analysisName, workflowRunID, checkoutPath, environment, githubAuth, githubUrl, doUpload, mode, outputDir, memoryFlag, addSnippetsFlag, threadsFlag, config, logger) {
|
||||
// Delete the tracer config env var to avoid tracing ourselves
|
||||
delete process.env[sharedEnv.ODASA_TRACER_CONFIGURATION];
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
await finalizeDatabaseCreation(config, threadsFlag, logger);
|
||||
}
|
||||
exports.runFinalize = runFinalize;
|
||||
async function runCleanup(config, cleanupLevel, logger) {
|
||||
logger.startGroup("Cleaning up databases");
|
||||
for (const language of config.languages) {
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
await codeql.databaseCleanup(databasePath, cleanupLevel);
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
exports.runCleanup = runCleanup;
|
||||
async function injectLinesOfCode(sarifFile, language, locPromise) {
|
||||
const lineCounts = await locPromise;
|
||||
const idPrefix = count_loc_1.getIdPrefix(language);
|
||||
if (language in lineCounts) {
|
||||
const sarif = JSON.parse(fs.readFileSync(sarifFile, "utf8"));
|
||||
if (Array.isArray(sarif.runs)) {
|
||||
for (const run of sarif.runs) {
|
||||
const ruleId = `${idPrefix}/summary/lines-of-code`;
|
||||
run.properties = run.properties || {};
|
||||
run.properties.metricResults = run.properties.metricResults || [];
|
||||
const rule = run.properties.metricResults.find(
|
||||
// the rule id can be in either of two places
|
||||
(r) => { var _a; return r.ruleId === ruleId || ((_a = r.rule) === null || _a === void 0 ? void 0 : _a.id) === ruleId; });
|
||||
// only add the baseline value if the rule already exists
|
||||
if (rule) {
|
||||
rule.baseline = lineCounts[language];
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(sarifFile, JSON.stringify(sarif));
|
||||
}
|
||||
}
|
||||
function printLinesOfCodeSummary(logger, language, lineCounts) {
|
||||
if (language in lineCounts) {
|
||||
logger.info(`Counted a baseline of ${lineCounts[language]} lines of code for ${language}.`);
|
||||
logger.info("Finalizing database creation");
|
||||
await finalizeDatabaseCreation(config, logger);
|
||||
logger.info("Analyzing database");
|
||||
const queriesStats = await runQueries(outputDir, memoryFlag, addSnippetsFlag, threadsFlag, config, logger);
|
||||
if (!doUpload) {
|
||||
logger.info("Not uploading results");
|
||||
return { ...queriesStats };
|
||||
}
|
||||
const uploadStats = await upload_lib.upload(outputDir, repositoryNwo, commitOid, ref, analysisKey, analysisName, workflowRunID, checkoutPath, environment, githubAuth, githubUrl, mode, logger);
|
||||
return { ...queriesStats, ...uploadStats };
|
||||
}
|
||||
exports.runAnalyze = runAnalyze;
|
||||
//# sourceMappingURL=analyze.js.map
|
||||
File diff suppressed because one or more lines are too long
200
lib/analyze.test.js
generated
200
lib/analyze.test.js
generated
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
@@ -6,95 +9,27 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const semver_1 = require("semver");
|
||||
const sinon_1 = __importDefault(require("sinon"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const analyze_1 = require("./analyze");
|
||||
const codeql_1 = require("./codeql");
|
||||
const count_loc_1 = require("./count-loc");
|
||||
const count = __importStar(require("./count-loc"));
|
||||
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);
|
||||
// Checks that the duration fields are populated for the correct language
|
||||
// and correct case of builtin or custom. Also checks the correct search
|
||||
// paths are set in the database analyze invocation.
|
||||
ava_1.default("status report fields and search path setting", async (t) => {
|
||||
const mockLinesOfCode = Object.values(languages_1.Language).reduce((obj, lang, i) => {
|
||||
// use a different line count for each language
|
||||
obj[lang] = i + 1;
|
||||
return obj;
|
||||
}, {});
|
||||
sinon_1.default.stub(count, "countLoc").resolves(mockLinesOfCode);
|
||||
let searchPathsUsed = [];
|
||||
// and correct case of builtin or custom.
|
||||
ava_1.default("status report fields", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
codeql_1.setCodeQL({
|
||||
databaseAnalyze: async () => undefined,
|
||||
});
|
||||
const memoryFlag = "";
|
||||
const addSnippetsFlag = "";
|
||||
const threadsFlag = "";
|
||||
const packs = {
|
||||
[languages_1.Language.cpp]: [
|
||||
{
|
||||
packName: "a/b",
|
||||
version: semver_1.clean("1.0.0"),
|
||||
},
|
||||
],
|
||||
[languages_1.Language.java]: [
|
||||
{
|
||||
packName: "c/d",
|
||||
version: semver_1.clean("2.0.0"),
|
||||
},
|
||||
],
|
||||
};
|
||||
for (const language of Object.values(languages_1.Language)) {
|
||||
codeql_1.setCodeQL({
|
||||
packDownload: async () => ({ packs: [] }),
|
||||
databaseRunQueries: async (_db, searchPath) => {
|
||||
searchPathsUsed.push(searchPath);
|
||||
},
|
||||
databaseInterpretResults: async (_db, _queriesRun, sarifFile) => {
|
||||
fs.writeFileSync(sarifFile, JSON.stringify({
|
||||
runs: [
|
||||
// variant 1 uses ruleId
|
||||
{
|
||||
properties: {
|
||||
metricResults: [
|
||||
{
|
||||
ruleId: `${count_loc_1.getIdPrefix(language)}/summary/lines-of-code`,
|
||||
value: 123,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// variant 2 uses rule.id
|
||||
{
|
||||
properties: {
|
||||
metricResults: [
|
||||
{
|
||||
rule: {
|
||||
id: `${count_loc_1.getIdPrefix(language)}/summary/lines-of-code`,
|
||||
},
|
||||
value: 123,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{},
|
||||
],
|
||||
}));
|
||||
return "";
|
||||
},
|
||||
});
|
||||
searchPathsUsed = [];
|
||||
const config = {
|
||||
languages: [language],
|
||||
queries: {},
|
||||
@@ -104,128 +39,25 @@ ava_1.default("status report fields and search path setting", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
gitHubVersion: {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
},
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
packs,
|
||||
};
|
||||
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
|
||||
fs.mkdirSync(util.getCodeQLDatabasePath(config.tempDir, language), {
|
||||
recursive: true,
|
||||
});
|
||||
config.queries[language] = {
|
||||
builtin: ["foo.ql"],
|
||||
custom: [],
|
||||
};
|
||||
const builtinStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
|
||||
const hasPacks = language in packs;
|
||||
const statusReportKeys = Object.keys(builtinStatusReport).sort();
|
||||
if (hasPacks) {
|
||||
t.deepEqual(statusReportKeys.length, 3, statusReportKeys.toString());
|
||||
t.deepEqual(statusReportKeys[0], `analyze_builtin_queries_${language}_duration_ms`);
|
||||
t.deepEqual(statusReportKeys[1], `analyze_custom_queries_${language}_duration_ms`);
|
||||
t.deepEqual(statusReportKeys[2], `interpret_results_${language}_duration_ms`);
|
||||
}
|
||||
else {
|
||||
t.deepEqual(statusReportKeys[0], `analyze_builtin_queries_${language}_duration_ms`);
|
||||
t.deepEqual(statusReportKeys[1], `interpret_results_${language}_duration_ms`);
|
||||
}
|
||||
const builtinStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, config, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(Object.keys(builtinStatusReport).length, 1);
|
||||
t.true(`analyze_builtin_queries_${language}_duration_ms` in builtinStatusReport);
|
||||
config.queries[language] = {
|
||||
builtin: [],
|
||||
custom: [
|
||||
{
|
||||
queries: ["foo.ql"],
|
||||
searchPath: "/1",
|
||||
},
|
||||
{
|
||||
queries: ["bar.ql"],
|
||||
searchPath: "/2",
|
||||
},
|
||||
],
|
||||
custom: ["foo.ql"],
|
||||
};
|
||||
const customStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, undefined, config, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 2);
|
||||
const customStatusReport = await analyze_1.runQueries(tmpDir, memoryFlag, addSnippetsFlag, threadsFlag, config, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(Object.keys(customStatusReport).length, 1);
|
||||
t.true(`analyze_custom_queries_${language}_duration_ms` in customStatusReport);
|
||||
const expectedSearchPathsUsed = hasPacks
|
||||
? [undefined, undefined, "/1", "/2", undefined]
|
||||
: [undefined, "/1", "/2"];
|
||||
t.deepEqual(searchPathsUsed, expectedSearchPathsUsed);
|
||||
t.true(`interpret_results_${language}_duration_ms` in customStatusReport);
|
||||
}
|
||||
verifyLineCounts(tmpDir);
|
||||
verifyQuerySuites(tmpDir);
|
||||
});
|
||||
function verifyLineCounts(tmpDir) {
|
||||
// eslint-disable-next-line github/array-foreach
|
||||
Object.keys(languages_1.Language).forEach((lang, i) => {
|
||||
verifyLineCountForFile(lang, path.join(tmpDir, `${lang}.sarif`), i + 1);
|
||||
});
|
||||
}
|
||||
function verifyLineCountForFile(lang, filePath, lineCount) {
|
||||
const idPrefix = count_loc_1.getIdPrefix(lang);
|
||||
const sarif = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||
t.deepEqual(sarif.runs[0].properties.metricResults, [
|
||||
{
|
||||
ruleId: `${idPrefix}/summary/lines-of-code`,
|
||||
value: 123,
|
||||
baseline: lineCount,
|
||||
},
|
||||
]);
|
||||
t.deepEqual(sarif.runs[1].properties.metricResults, [
|
||||
{
|
||||
rule: {
|
||||
id: `${idPrefix}/summary/lines-of-code`,
|
||||
},
|
||||
value: 123,
|
||||
baseline: lineCount,
|
||||
},
|
||||
]);
|
||||
// when the rule doesn't exist, it should not be added
|
||||
t.deepEqual(sarif.runs[2].properties.metricResults, []);
|
||||
}
|
||||
function verifyQuerySuites(tmpDir) {
|
||||
const qlsContent = [
|
||||
{
|
||||
query: "foo.ql",
|
||||
},
|
||||
];
|
||||
const qlsContent2 = [
|
||||
{
|
||||
query: "bar.ql",
|
||||
},
|
||||
];
|
||||
const qlsPackContentCpp = [
|
||||
{
|
||||
qlpack: "a/b",
|
||||
version: "1.0.0",
|
||||
},
|
||||
];
|
||||
const qlsPackContentJava = [
|
||||
{
|
||||
qlpack: "c/d",
|
||||
version: "2.0.0",
|
||||
},
|
||||
];
|
||||
for (const lang of Object.values(languages_1.Language)) {
|
||||
t.deepEqual(readContents(`${lang}-queries-builtin.qls`), qlsContent);
|
||||
t.deepEqual(readContents(`${lang}-queries-custom-0.qls`), qlsContent);
|
||||
t.deepEqual(readContents(`${lang}-queries-custom-1.qls`), qlsContent2);
|
||||
const packSuiteName = `${lang}-queries-packs.qls`;
|
||||
if (lang === languages_1.Language.cpp) {
|
||||
t.deepEqual(readContents(packSuiteName), qlsPackContentCpp);
|
||||
}
|
||||
else if (lang === languages_1.Language.java) {
|
||||
t.deepEqual(readContents(packSuiteName), qlsPackContentJava);
|
||||
}
|
||||
else {
|
||||
t.false(fs.existsSync(path.join(tmpDir, "codeql_databases", packSuiteName)));
|
||||
}
|
||||
}
|
||||
function readContents(name) {
|
||||
const x = fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8");
|
||||
console.log(x);
|
||||
return yaml.safeLoad(fs.readFileSync(path.join(tmpDir, "codeql_databases", name), "utf8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=analyze.test.js.map
|
||||
File diff suppressed because one or more lines are too long
33
lib/api-client.js
generated
33
lib/api-client.js
generated
@@ -10,31 +10,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path = __importStar(require("path"));
|
||||
const githubUtils = __importStar(require("@actions/github/lib/utils"));
|
||||
const retry = __importStar(require("@octokit/plugin-retry"));
|
||||
const console_log_level_1 = __importDefault(require("console-log-level"));
|
||||
const path = __importStar(require("path"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
var DisallowedAPIVersionReason;
|
||||
(function (DisallowedAPIVersionReason) {
|
||||
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_OLD"] = 0] = "ACTION_TOO_OLD";
|
||||
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_NEW"] = 1] = "ACTION_TOO_NEW";
|
||||
})(DisallowedAPIVersionReason = exports.DisallowedAPIVersionReason || (exports.DisallowedAPIVersionReason = {}));
|
||||
exports.getApiClient = function (apiDetails, { allowExternal = false } = {}) {
|
||||
const auth = (allowExternal && apiDetails.externalRepoAuth) || apiDetails.auth;
|
||||
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(auth, {
|
||||
baseUrl: getApiUrl(apiDetails.url),
|
||||
userAgent: `CodeQL-${util_1.getMode()}/${pkg.version}`,
|
||||
return new retryingOctokit(githubUtils.getOctokitOptions(githubAuth, {
|
||||
baseUrl: getApiUrl(githubUrl),
|
||||
userAgent: "CodeQL Action",
|
||||
log: console_log_level_1.default({ level: "debug" }),
|
||||
}));
|
||||
};
|
||||
function getApiUrl(githubUrl) {
|
||||
const url = new URL(githubUrl);
|
||||
// If we detect this is trying to connect to github.com
|
||||
// If we detect this is trying to be to github.com
|
||||
// then return with a fixed canonical URL.
|
||||
if (url.hostname === "github.com" || url.hostname === "api.github.com") {
|
||||
return "https://api.github.com";
|
||||
@@ -44,14 +39,10 @@ function getApiUrl(githubUrl) {
|
||||
return url.toString();
|
||||
}
|
||||
// Temporary function to aid in the transition to running on and off of github actions.
|
||||
// Once all code has been converted this function should be removed or made canonical
|
||||
// Once all code has been coverted this function should be removed or made canonical
|
||||
// and called only from the action entrypoints.
|
||||
function getActionsApiClient() {
|
||||
const apiDetails = {
|
||||
auth: actions_util_1.getRequiredInput("token"),
|
||||
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
return exports.getApiClient(apiDetails);
|
||||
function getActionsApiClient(allowLocalRun = false) {
|
||||
return exports.getApiClient(actions_util_1.getRequiredInput("token"), actions_util_1.getRequiredEnvParam("GITHUB_SERVER_URL"), allowLocalRun);
|
||||
}
|
||||
exports.getActionsApiClient = getActionsApiClient;
|
||||
//# sourceMappingURL=api-client.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA6B;AAE7B,uEAAyD;AACzD,6DAA+C;AAC/C,0EAAgD;AAEhD,iDAAkD;AAClD,iCAAsD;AAEtD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,IAAY,0BAGX;AAHD,WAAY,0BAA0B;IACpC,+FAAc,CAAA;IACd,+FAAc,CAAA;AAChB,CAAC,EAHW,0BAA0B,GAA1B,kCAA0B,KAA1B,kCAA0B,QAGrC;AAeY,QAAA,YAAY,GAAG,UAC1B,UAAoC,EACpC,EAAE,aAAa,GAAG,KAAK,EAAE,GAAG,EAAE;IAE9B,MAAM,IAAI,GACR,CAAC,aAAa,IAAI,UAAU,CAAC,gBAAgB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;IACpE,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,IAAI,eAAe,CACxB,WAAW,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAClC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAClC,SAAS,EAAE,UAAU,cAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE;QAC/C,GAAG,EAAE,2BAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;KACzC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAE/B,uDAAuD;IACvD,0CAA0C;IAC1C,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,GAAG,CAAC,QAAQ,KAAK,gBAAgB,EAAE;QACtE,OAAO,wBAAwB,CAAC;KACjC;IAED,6BAA6B;IAC7B,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,uFAAuF;AACvF,qFAAqF;AACrF,+CAA+C;AAC/C,SAAgB,mBAAmB;IACjC,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,+BAAgB,CAAC,OAAO,CAAC;QAC/B,GAAG,EAAE,0BAAmB,CAAC,mBAAmB,CAAC;KAC9C,CAAC;IAEF,OAAO,oBAAY,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAPD,kDAOC"}
|
||||
{"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"}
|
||||
79
lib/api-client.test.js
generated
79
lib/api-client.test.js
generated
@@ -1,79 +0,0 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const githubUtils = __importStar(require("@actions/github/lib/utils"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const sinon_1 = __importDefault(require("sinon"));
|
||||
const api_client_1 = require("./api-client");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
let pluginStub;
|
||||
let githubStub;
|
||||
ava_1.default.beforeEach(() => {
|
||||
pluginStub = sinon_1.default.stub(githubUtils.GitHub, "plugin");
|
||||
githubStub = sinon_1.default.stub();
|
||||
pluginStub.returns(githubStub);
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
|
||||
});
|
||||
ava_1.default("Get the client API", async (t) => {
|
||||
doTest(t, {
|
||||
auth: "xyz",
|
||||
externalRepoAuth: "abc",
|
||||
url: "http://hucairz",
|
||||
}, undefined, {
|
||||
auth: "token xyz",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
});
|
||||
});
|
||||
ava_1.default("Get the client API external", async (t) => {
|
||||
doTest(t, {
|
||||
auth: "xyz",
|
||||
externalRepoAuth: "abc",
|
||||
url: "http://hucairz",
|
||||
}, { allowExternal: true }, {
|
||||
auth: "token abc",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
});
|
||||
});
|
||||
ava_1.default("Get the client API external not present", async (t) => {
|
||||
doTest(t, {
|
||||
auth: "xyz",
|
||||
url: "http://hucairz",
|
||||
}, { allowExternal: true }, {
|
||||
auth: "token xyz",
|
||||
baseUrl: "http://hucairz/api/v3",
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
});
|
||||
});
|
||||
ava_1.default("Get the client API with github url", async (t) => {
|
||||
doTest(t, {
|
||||
auth: "xyz",
|
||||
url: "https://github.com/some/invalid/url",
|
||||
}, undefined, {
|
||||
auth: "token xyz",
|
||||
baseUrl: "https://api.github.com",
|
||||
userAgent: `CodeQL-Action/${pkg.version}`,
|
||||
});
|
||||
});
|
||||
function doTest(t, clientArgs, clientOptions, expected) {
|
||||
api_client_1.getApiClient(clientArgs, clientOptions);
|
||||
const firstCallArgs = githubStub.args[0];
|
||||
// log is a function, so we don't need to test for equality of it
|
||||
delete firstCallArgs[0].log;
|
||||
t.deepEqual(firstCallArgs, [expected]);
|
||||
}
|
||||
//# sourceMappingURL=api-client.test.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../src/api-client.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uEAAyD;AACzD,8CAA6C;AAC7C,kDAA0B;AAE1B,6CAA4C;AAC5C,mDAA6C;AAC7C,iCAAqD;AAErD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,IAAI,UAA2B,CAAC;AAChC,IAAI,UAA2B,CAAC;AAEhC,aAAI,CAAC,UAAU,CAAC,GAAG,EAAE;IACnB,UAAU,GAAG,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,UAAU,GAAG,eAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrC,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,6BAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9C,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;QACvB,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,yCAAyC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC1D,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,gBAAgB;KACtB,EACD,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,uBAAuB;QAChC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,oCAAoC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrD,MAAM,CACJ,CAAC,EACD;QACE,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,qCAAqC;KAC3C,EACD,SAAS,EACT;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,wBAAwB;QACjC,SAAS,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE;KAC1C,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,MAAM,CACb,CAA4B,EAC5B,UAAe,EACf,aAAkB,EAClB,QAAa;IAEb,yBAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAExC,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,iEAAiE;IACjE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5B,CAAC,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
||||
@@ -1 +0,0 @@
|
||||
{ "maximumVersion": "3.2", "minimumVersion": "2.22" }
|
||||
29
lib/autobuild-action.js
generated
29
lib/autobuild-action.js
generated
@@ -8,36 +8,33 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const autobuild_1 = require("./autobuild");
|
||||
const config_utils = __importStar(require("./config-utils"));
|
||||
const logging_1 = require("./logging");
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
async function sendCompletedStatusReport(startedAt, allLanguages, failingLanguage, cause) {
|
||||
var _a, _b;
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
|
||||
const status = failingLanguage !== undefined || cause !== undefined
|
||||
? "failure"
|
||||
: "success";
|
||||
const statusReportBase = await actions_util_1.createStatusReportBase("autobuild", status, startedAt, (_a = cause) === null || _a === void 0 ? void 0 : _a.message, (_b = cause) === null || _b === void 0 ? void 0 : _b.stack);
|
||||
const statusReportBase = await actionsUtil.createStatusReportBase("autobuild", status, startedAt, (_a = cause) === null || _a === void 0 ? void 0 : _a.message, (_b = cause) === null || _b === void 0 ? void 0 : _b.stack);
|
||||
const statusReport = {
|
||||
...statusReportBase,
|
||||
autobuild_languages: allLanguages.join(","),
|
||||
autobuild_failure: failingLanguage,
|
||||
};
|
||||
await actions_util_1.sendStatusReport(statusReport);
|
||||
await actionsUtil.sendStatusReport(statusReport);
|
||||
}
|
||||
async function run() {
|
||||
const logger = logging_1.getActionsLogger();
|
||||
const startedAt = new Date();
|
||||
let language = undefined;
|
||||
try {
|
||||
if (!(await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("autobuild", "starting", startedAt)))) {
|
||||
actionsUtil.prepareLocalRunEnvironment();
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("autobuild", "starting", startedAt), true))) {
|
||||
return;
|
||||
}
|
||||
const config = await config_utils.getConfig(actions_util_1.getTemporaryDirectory(), logger);
|
||||
const config = await config_utils.getConfig(actionsUtil.getRequiredEnvParam("RUNNER_TEMP"), logger);
|
||||
if (config === undefined) {
|
||||
throw new Error("Config file could not be found at expected location. Has the 'init' action been called?");
|
||||
}
|
||||
@@ -54,14 +51,8 @@ async function run() {
|
||||
}
|
||||
await sendCompletedStatusReport(startedAt, language ? [language] : []);
|
||||
}
|
||||
async function runWrapper() {
|
||||
try {
|
||||
await run();
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`autobuild action failed. ${error}`);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
void runWrapper();
|
||||
run().catch((e) => {
|
||||
core.setFailed(`autobuild action failed. ${e}`);
|
||||
console.log(e);
|
||||
});
|
||||
//# sourceMappingURL=autobuild-action.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"autobuild-action.js","sourceRoot":"","sources":["../src/autobuild-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,iDAKwB;AACxB,2CAAuE;AACvE,6DAA+C;AAE/C,uCAA6C;AAC7C,iCAAqD;AAErD,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AASvC,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GACV,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAClD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,gBAAgB,GAAG,MAAM,qCAAsB,CACnD,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CACb,CAAC;IACF,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,+BAAgB,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAyB,SAAS,CAAC;IAC/C,IAAI;QACF,IACE,CAAC,CAAC,MAAM,+BAAgB,CACtB,MAAM,qCAAsB,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,CACjE,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CACzC,oCAAqB,EAAE,EACvB,MAAM,CACP,CAAC;QACF,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;SACH;QACD,QAAQ,GAAG,sCAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,QAAQ,KAAK,SAAS,EAAE;YAC1B,MAAM,wBAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9C;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CACZ,mIAAmI,KAAK,CAAC,OAAO,EAAE,CACnJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,yBAAyB,CAC7B,SAAS,EACT,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAC1B,QAAQ,EACR,KAAK,CACN,CAAC;QACF,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
|
||||
{"version":3,"file":"autobuild-action.js","sourceRoot":"","sources":["../src/autobuild-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,2CAAuE;AACvE,6DAA+C;AAE/C,uCAA6C;AAS7C,KAAK,UAAU,yBAAyB,CACtC,SAAe,EACf,YAAsB,EACtB,eAAwB,EACxB,KAAa;;IAEb,MAAM,MAAM,GACV,eAAe,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAClD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,WAAW,EACX,MAAM,EACN,SAAS,QACT,KAAK,0CAAE,OAAO,QACd,KAAK,0CAAE,KAAK,CACb,CAAC;IACF,MAAM,YAAY,GAA0B;QAC1C,GAAG,gBAAgB;QACnB,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3C,iBAAiB,EAAE,eAAe;KACnC,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAyB,SAAS,CAAC;IAC/C,IAAI;QACF,WAAW,CAAC,0BAA0B,EAAE,CAAC;QACzC,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,WAAW,EACX,UAAU,EACV,SAAS,CACV,EACD,IAAI,CACL,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CACzC,WAAW,CAAC,mBAAmB,CAAC,aAAa,CAAC,EAC9C,MAAM,CACP,CAAC;QACF,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;SACH;QACD,QAAQ,GAAG,sCAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,QAAQ,KAAK,SAAS,EAAE;YAC1B,MAAM,wBAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9C;KACF;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CACZ,mIAAmI,KAAK,CAAC,OAAO,EAAE,CACnJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,yBAAyB,CAC7B,SAAS,EACT,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAC1B,QAAQ,EACR,KAAK,CACN,CAAC;QACF,OAAO;KACR;IAED,MAAM,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAChB,IAAI,CAAC,SAAS,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
||||
462
lib/codeql.js
generated
462
lib/codeql.js
generated
@@ -10,115 +10,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const http = __importStar(require("@actions/http-client"));
|
||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
||||
const query_string_1 = __importDefault(require("query-string"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const stream = __importStar(require("stream"));
|
||||
const globalutil = __importStar(require("util"));
|
||||
const v4_1 = __importDefault(require("uuid/v4"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
const api = __importStar(require("./api-client"));
|
||||
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
|
||||
const error_matcher_1 = require("./error-matcher");
|
||||
const toolcache = __importStar(require("./toolcache"));
|
||||
const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
||||
const util = __importStar(require("./util"));
|
||||
class CommandInvocationError extends Error {
|
||||
constructor(cmd, args, exitCode, error) {
|
||||
super(`Failure invoking ${cmd} with arguments ${args}.\n
|
||||
Exit code ${exitCode} and error was:\n
|
||||
${error}`);
|
||||
}
|
||||
}
|
||||
exports.CommandInvocationError = CommandInvocationError;
|
||||
/**
|
||||
* Stores the CodeQL object, and is populated by `setupCodeQL` or `getCodeQL`.
|
||||
* Can be overridden in tests using `setCodeQL`.
|
||||
*/
|
||||
let cachedCodeQL = undefined;
|
||||
const CODEQL_BUNDLE_VERSION = defaults.bundleVersion;
|
||||
const CODEQL_BUNDLE_NAME = "codeql-bundle.tar.gz";
|
||||
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
|
||||
function getCodeQLBundleName() {
|
||||
let platform;
|
||||
if (process.platform === "win32") {
|
||||
platform = "win64";
|
||||
}
|
||||
else if (process.platform === "linux") {
|
||||
platform = "linux64";
|
||||
}
|
||||
else if (process.platform === "darwin") {
|
||||
platform = "osx64";
|
||||
}
|
||||
else {
|
||||
return "codeql-bundle.tar.gz";
|
||||
}
|
||||
return `codeql-bundle-${platform}.tar.gz`;
|
||||
}
|
||||
function getCodeQLActionRepository(logger) {
|
||||
if (!util.isActions()) {
|
||||
function getCodeQLActionRepository(mode) {
|
||||
if (mode !== "actions") {
|
||||
return CODEQL_DEFAULT_ACTION_REPOSITORY;
|
||||
}
|
||||
else {
|
||||
return getActionsCodeQLActionRepository(logger);
|
||||
}
|
||||
}
|
||||
exports.getCodeQLActionRepository = getCodeQLActionRepository;
|
||||
function getActionsCodeQLActionRepository(logger) {
|
||||
if (process.env["GITHUB_ACTION_REPOSITORY"] !== undefined) {
|
||||
return process.env["GITHUB_ACTION_REPOSITORY"];
|
||||
}
|
||||
// The Actions Runner used with GitHub Enterprise Server 2.22 did not set the GITHUB_ACTION_REPOSITORY variable.
|
||||
// This fallback logic can be removed after the end-of-support for 2.22 on 2021-09-23.
|
||||
if (actions_util_1.isRunningLocalAction()) {
|
||||
// This handles the case where the Action does not come from an Action repository,
|
||||
// e.g. our integration tests which use the Action code from the current checkout.
|
||||
logger.info("The CodeQL Action is checked out locally. Using the default CodeQL Action repository.");
|
||||
// Actions do not know their own repository name,
|
||||
// so we currently use this hack to find the name based on where our files are.
|
||||
// This can be removed once the change to the runner in https://github.com/actions/runner/pull/585 is deployed.
|
||||
const runnerTemp = actions_util_1.getRequiredEnvParam("RUNNER_TEMP");
|
||||
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
|
||||
const relativeScriptPath = path.relative(actionsDirectory, __filename);
|
||||
// This handles the case where the Action does not come from an Action repository,
|
||||
// e.g. our integration tests which use the Action code from the current checkout.
|
||||
if (relativeScriptPath.startsWith("..") ||
|
||||
path.isAbsolute(relativeScriptPath)) {
|
||||
return CODEQL_DEFAULT_ACTION_REPOSITORY;
|
||||
}
|
||||
logger.info("GITHUB_ACTION_REPOSITORY environment variable was not set. Falling back to legacy method of finding the GitHub Action.");
|
||||
const relativeScriptPathParts = actions_util_1.getRelativeScriptPath().split(path.sep);
|
||||
const relativeScriptPathParts = relativeScriptPath.split(path.sep);
|
||||
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
||||
}
|
||||
async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
||||
const codeQLActionRepository = getCodeQLActionRepository(logger);
|
||||
async function getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger) {
|
||||
const codeQLActionRepository = getCodeQLActionRepository(mode);
|
||||
const potentialDownloadSources = [
|
||||
// This GitHub instance, and this Action.
|
||||
[apiDetails.url, codeQLActionRepository],
|
||||
[githubUrl, codeQLActionRepository],
|
||||
// This GitHub instance, and the canonical Action.
|
||||
[apiDetails.url, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
[githubUrl, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
// GitHub.com, and the canonical Action.
|
||||
[util.GITHUB_DOTCOM_URL, CODEQL_DEFAULT_ACTION_REPOSITORY],
|
||||
];
|
||||
// We now filter out any duplicates.
|
||||
// Duplicates will happen either because the GitHub instance is GitHub.com, or because the Action is not a fork.
|
||||
const uniqueDownloadSources = potentialDownloadSources.filter((source, index, self) => {
|
||||
return !self.slice(0, index).some((other) => fast_deep_equal_1.default(source, other));
|
||||
});
|
||||
const codeQLBundleName = getCodeQLBundleName();
|
||||
if (variant === util.GitHubVariant.GHAE) {
|
||||
try {
|
||||
const release = await api
|
||||
.getApiClient(apiDetails)
|
||||
.request("GET /enterprise/code-scanning/codeql-bundle/find/{tag}", {
|
||||
tag: CODEQL_BUNDLE_VERSION,
|
||||
});
|
||||
const assetID = release.data.assets[codeQLBundleName];
|
||||
if (assetID !== undefined) {
|
||||
const download = await api
|
||||
.getApiClient(apiDetails)
|
||||
.request("GET /enterprise/code-scanning/codeql-bundle/download/{asset_id}", { asset_id: assetID });
|
||||
const downloadURL = download.data.url;
|
||||
logger.info(`Found CodeQL bundle at GitHub AE endpoint with URL ${downloadURL}.`);
|
||||
return downloadURL;
|
||||
}
|
||||
else {
|
||||
logger.info(`Attempted to fetch bundle from GitHub AE endpoint but the bundle ${codeQLBundleName} was not found in the assets ${JSON.stringify(release.data.assets)}.`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
logger.info(`Attempted to fetch bundle from GitHub AE endpoint but got error ${e}.`);
|
||||
}
|
||||
}
|
||||
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.
|
||||
@@ -128,13 +74,15 @@ async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
||||
}
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release = await api.getApiClient(apiDetails).repos.getReleaseByTag({
|
||||
const release = await api
|
||||
.getApiClient(githubAuth, githubUrl)
|
||||
.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: CODEQL_BUNDLE_VERSION,
|
||||
});
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name === codeQLBundleName) {
|
||||
if (asset.name === CODEQL_BUNDLE_NAME) {
|
||||
logger.info(`Found CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} with URL ${asset.url}.`);
|
||||
return asset.url;
|
||||
}
|
||||
@@ -144,68 +92,55 @@ async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
||||
logger.info(`Looked for CodeQL bundle in ${downloadSource[1]} on ${downloadSource[0]} but got error ${e}.`);
|
||||
}
|
||||
}
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${codeQLBundleName}`;
|
||||
return `https://github.com/${CODEQL_DEFAULT_ACTION_REPOSITORY}/releases/download/${CODEQL_BUNDLE_VERSION}/${CODEQL_BUNDLE_NAME}`;
|
||||
}
|
||||
async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger) {
|
||||
// We have to download CodeQL manually because the toolcache doesn't support Accept headers.
|
||||
// This can be removed once https://github.com/actions/toolkit/pull/530 is merged and released.
|
||||
async function toolcacheDownloadTool(url, headers, tempDir, logger) {
|
||||
const client = new http.HttpClient("CodeQL Action");
|
||||
const dest = path.join(tempDir, v4_1.default());
|
||||
const response = await client.get(url, headers);
|
||||
if (response.message.statusCode !== 200) {
|
||||
logger.info(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
throw new Error(`Unexpected HTTP response: ${response.message.statusCode}`);
|
||||
}
|
||||
const pipeline = globalutil.promisify(stream.pipeline);
|
||||
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||
await pipeline(response.message, fs.createWriteStream(dest));
|
||||
return dest;
|
||||
}
|
||||
async function setupCodeQL(codeqlURL, 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;
|
||||
try {
|
||||
// We use the special value of 'latest' to prioritize the version in the
|
||||
// defaults over any pinned cached version.
|
||||
const forceLatest = codeqlURL === "latest";
|
||||
if (forceLatest) {
|
||||
codeqlURL = undefined;
|
||||
}
|
||||
let codeqlFolder;
|
||||
let codeqlURLVersion;
|
||||
if (codeqlURL && !codeqlURL.startsWith("http")) {
|
||||
codeqlFolder = await toolcache.extractTar(codeqlURL, tempDir, logger);
|
||||
codeqlURLVersion = "local";
|
||||
const codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`, logger);
|
||||
let codeqlFolder = toolcache.find("CodeQL", codeqlURLVersion);
|
||||
if (codeqlFolder) {
|
||||
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||
}
|
||||
else {
|
||||
codeqlURLVersion = getCodeQLURLVersion(codeqlURL || `/${CODEQL_BUNDLE_VERSION}/`);
|
||||
const codeqlURLSemVer = convertToSemVer(codeqlURLVersion, logger);
|
||||
// If we find the specified version, we always use that.
|
||||
codeqlFolder = toolcache.find("CodeQL", codeqlURLSemVer, toolCacheDir, logger);
|
||||
// If we don't find the requested version, in some cases we may allow a
|
||||
// different version to save download time if the version hasn't been
|
||||
// specified explicitly (in which case we always honor it).
|
||||
if (!codeqlFolder && !codeqlURL && !forceLatest) {
|
||||
const codeqlVersions = toolcache.findAllVersions("CodeQL", toolCacheDir, logger);
|
||||
if (codeqlVersions.length === 1) {
|
||||
const tmpCodeqlFolder = toolcache.find("CodeQL", codeqlVersions[0], toolCacheDir, logger);
|
||||
if (fs.existsSync(path.join(tmpCodeqlFolder, "pinned-version"))) {
|
||||
logger.debug(`CodeQL in cache overriding the default ${CODEQL_BUNDLE_VERSION}`);
|
||||
codeqlFolder = tmpCodeqlFolder;
|
||||
}
|
||||
}
|
||||
if (!codeqlURL) {
|
||||
codeqlURL = await getCodeQLBundleDownloadURL(githubAuth, githubUrl, mode, logger);
|
||||
}
|
||||
if (codeqlFolder) {
|
||||
logger.debug(`CodeQL found in cache ${codeqlFolder}`);
|
||||
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.
|
||||
// This avoids leaking Enterprise tokens to dotcom.
|
||||
if (codeqlURL.startsWith(`${githubUrl}/`)) {
|
||||
logger.debug("Downloading CodeQL bundle with token.");
|
||||
headers.authorization = `token ${githubAuth}`;
|
||||
}
|
||||
else {
|
||||
if (!codeqlURL) {
|
||||
codeqlURL = await getCodeQLBundleDownloadURL(apiDetails, variant, logger);
|
||||
}
|
||||
const parsedCodeQLURL = new URL(codeqlURL);
|
||||
const parsedQueryString = query_string_1.default.parse(parsedCodeQLURL.search);
|
||||
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.
|
||||
// This avoids leaking Enterprise tokens to dotcom.
|
||||
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
||||
if (codeqlURL.startsWith(`${apiDetails.url}/`) &&
|
||||
parsedQueryString["token"] === undefined) {
|
||||
logger.debug("Downloading CodeQL bundle with token.");
|
||||
headers.authorization = `token ${apiDetails.auth}`;
|
||||
}
|
||||
else {
|
||||
logger.debug("Downloading CodeQL bundle without token.");
|
||||
}
|
||||
logger.info(`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`);
|
||||
const codeqlPath = await toolcache.downloadTool(codeqlURL, tempDir, headers);
|
||||
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
|
||||
const codeqlExtracted = await toolcache.extractTar(codeqlPath, tempDir, logger);
|
||||
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLSemVer, toolCacheDir, logger);
|
||||
logger.debug("Downloading CodeQL bundle without token.");
|
||||
}
|
||||
logger.info(`Downloading CodeQL tools from ${codeqlURL}. This may take a while.`);
|
||||
const codeqlPath = await toolcacheDownloadTool(codeqlURL, headers, tempDir, logger);
|
||||
logger.debug(`CodeQL bundle download to ${codeqlPath} complete.`);
|
||||
const codeqlExtracted = await toolcache.extractTar(codeqlPath);
|
||||
codeqlFolder = await toolcache.cacheDir(codeqlExtracted, "CodeQL", codeqlURLVersion);
|
||||
}
|
||||
let codeqlCmd = path.join(codeqlFolder, "codeql", "codeql");
|
||||
if (process.platform === "win32") {
|
||||
@@ -215,7 +150,7 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant
|
||||
throw new Error(`Unsupported platform: ${process.platform}`);
|
||||
}
|
||||
cachedCodeQL = getCodeQLForCmd(codeqlCmd);
|
||||
return { codeql: cachedCodeQL, toolsVersion: codeqlURLVersion };
|
||||
return cachedCodeQL;
|
||||
}
|
||||
catch (e) {
|
||||
logger.error(e);
|
||||
@@ -223,26 +158,23 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant
|
||||
}
|
||||
}
|
||||
exports.setupCodeQL = setupCodeQL;
|
||||
function getCodeQLURLVersion(url) {
|
||||
function getCodeQLURLVersion(url, logger) {
|
||||
const match = url.match(/\/codeql-bundle-(.*)\//);
|
||||
if (match === null || match.length < 2) {
|
||||
throw new Error(`Malformed tools url: ${url}. Version could not be inferred`);
|
||||
}
|
||||
return match[1];
|
||||
}
|
||||
exports.getCodeQLURLVersion = getCodeQLURLVersion;
|
||||
function convertToSemVer(version, logger) {
|
||||
let version = match[1];
|
||||
if (!semver.valid(version)) {
|
||||
logger.debug(`Bundle version ${version} is not in SemVer format. Will treat it as pre-release 0.0.0-${version}.`);
|
||||
version = `0.0.0-${version}`;
|
||||
}
|
||||
const s = semver.clean(version);
|
||||
if (!s) {
|
||||
throw new Error(`Bundle version ${version} is not in SemVer format.`);
|
||||
throw new Error(`Malformed tools url ${url}. Version should be in SemVer format but have ${version} instead`);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
exports.convertToSemVer = convertToSemVer;
|
||||
exports.getCodeQLURLVersion = getCodeQLURLVersion;
|
||||
/**
|
||||
* Use the CodeQL executable located at the given path.
|
||||
*/
|
||||
@@ -280,13 +212,8 @@ function setCodeQL(partialCodeql) {
|
||||
runAutobuild: resolveFunction(partialCodeql, "runAutobuild"),
|
||||
extractScannedLanguage: resolveFunction(partialCodeql, "extractScannedLanguage"),
|
||||
finalizeDatabase: resolveFunction(partialCodeql, "finalizeDatabase"),
|
||||
resolveLanguages: resolveFunction(partialCodeql, "resolveLanguages"),
|
||||
resolveQueries: resolveFunction(partialCodeql, "resolveQueries"),
|
||||
packDownload: resolveFunction(partialCodeql, "packDownload"),
|
||||
databaseCleanup: resolveFunction(partialCodeql, "databaseCleanup"),
|
||||
databaseBundle: resolveFunction(partialCodeql, "databaseBundle"),
|
||||
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
|
||||
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
|
||||
databaseAnalyze: resolveFunction(partialCodeql, "databaseAnalyze"),
|
||||
};
|
||||
return cachedCodeQL;
|
||||
}
|
||||
@@ -311,16 +238,13 @@ function getCodeQLForCmd(cmd) {
|
||||
return cmd;
|
||||
},
|
||||
async printVersion() {
|
||||
await runTool(cmd, ["version", "--format=json"]);
|
||||
await new toolrunnner.ToolRunner(cmd, [
|
||||
"version",
|
||||
"--format=json",
|
||||
]).exec();
|
||||
},
|
||||
async getTracerEnv(databasePath) {
|
||||
// Write tracer-env.js to a temp location.
|
||||
// BEWARE: The name and location of this file is recognized by `codeql database
|
||||
// trace-command` in order to enable special support for concatenable tracer
|
||||
// configurations. Consequently the name must not be changed.
|
||||
// (This warning can be removed once a different way to recognize the
|
||||
// action/runner has been implemented in `codeql database trace-command`
|
||||
// _and_ is present in the latest supported CLI release.)
|
||||
const tracerEnvJs = path.resolve(databasePath, "working", "tracer-env.js");
|
||||
fs.mkdirSync(path.dirname(tracerEnvJs), { recursive: true });
|
||||
fs.writeFileSync(tracerEnvJs, `
|
||||
@@ -335,14 +259,8 @@ function getCodeQLForCmd(cmd) {
|
||||
}
|
||||
process.stdout.write(process.argv[2]);
|
||||
fs.writeFileSync(process.argv[2], JSON.stringify(env), 'utf-8');`);
|
||||
// BEWARE: The name and location of this file is recognized by `codeql database
|
||||
// trace-command` in order to enable special support for concatenable tracer
|
||||
// configurations. Consequently the name must not be changed.
|
||||
// (This warning can be removed once a different way to recognize the
|
||||
// action/runner has been implemented in `codeql database trace-command`
|
||||
// _and_ is present in the latest supported CLI release.)
|
||||
const envFile = path.resolve(databasePath, "working", "env.tmp");
|
||||
await runTool(cmd, [
|
||||
await new toolrunnner.ToolRunner(cmd, [
|
||||
"database",
|
||||
"trace-command",
|
||||
databasePath,
|
||||
@@ -350,18 +268,18 @@ function getCodeQLForCmd(cmd) {
|
||||
process.execPath,
|
||||
tracerEnvJs,
|
||||
envFile,
|
||||
]);
|
||||
]).exec();
|
||||
return JSON.parse(fs.readFileSync(envFile, "utf-8"));
|
||||
},
|
||||
async databaseInit(databasePath, language, sourceRoot) {
|
||||
await runTool(cmd, [
|
||||
await new toolrunnner.ToolRunner(cmd, [
|
||||
"database",
|
||||
"init",
|
||||
databasePath,
|
||||
`--language=${language}`,
|
||||
`--source-root=${sourceRoot}`,
|
||||
...getExtraOptionsFromEnv(["database", "init"]),
|
||||
]);
|
||||
]).exec();
|
||||
},
|
||||
async runAutobuild(language) {
|
||||
const cmdName = process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh";
|
||||
@@ -377,12 +295,12 @@ function getCodeQLForCmd(cmd) {
|
||||
"-Dhttp.keepAlive=false",
|
||||
"-Dmaven.wagon.http.pool=false",
|
||||
].join(" ");
|
||||
await runTool(autobuildCmd);
|
||||
await new toolrunnner.ToolRunner(autobuildCmd).exec();
|
||||
},
|
||||
async extractScannedLanguage(databasePath, language) {
|
||||
// Get extractor location
|
||||
let extractorPath = "";
|
||||
await new toolrunner.ToolRunner(cmd, [
|
||||
await new toolrunnner.ToolRunner(cmd, [
|
||||
"resolve",
|
||||
"extractor",
|
||||
"--format=json",
|
||||
@@ -412,26 +330,14 @@ function getCodeQLForCmd(cmd) {
|
||||
traceCommand,
|
||||
], error_matcher_1.errorMatchers);
|
||||
},
|
||||
async finalizeDatabase(databasePath, threadsFlag) {
|
||||
async finalizeDatabase(databasePath) {
|
||||
await toolrunner_error_catcher_1.toolrunnerErrorCatcher(cmd, [
|
||||
"database",
|
||||
"finalize",
|
||||
"--finalize-dataset",
|
||||
threadsFlag,
|
||||
...getExtraOptionsFromEnv(["database", "finalize"]),
|
||||
databasePath,
|
||||
], error_matcher_1.errorMatchers);
|
||||
},
|
||||
async resolveLanguages() {
|
||||
const codeqlArgs = ["resolve", "languages", "--format=json"];
|
||||
const output = await runTool(cmd, codeqlArgs);
|
||||
try {
|
||||
return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unexpected output from codeql resolve languages: ${e}`);
|
||||
}
|
||||
},
|
||||
async resolveQueries(queries, extraSearchPath) {
|
||||
const codeqlArgs = [
|
||||
"resolve",
|
||||
@@ -441,184 +347,76 @@ function getCodeQLForCmd(cmd) {
|
||||
...getExtraOptionsFromEnv(["resolve", "queries"]),
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
codeqlArgs.push("--additional-packs", extraSearchPath);
|
||||
}
|
||||
const output = await runTool(cmd, codeqlArgs);
|
||||
try {
|
||||
return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unexpected output from codeql resolve queries: ${e}`);
|
||||
codeqlArgs.push("--search-path", extraSearchPath);
|
||||
}
|
||||
let output = "";
|
||||
await new toolrunnner.ToolRunner(cmd, codeqlArgs, {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
output += data.toString();
|
||||
},
|
||||
},
|
||||
}).exec();
|
||||
return JSON.parse(output);
|
||||
},
|
||||
async databaseRunQueries(databasePath, extraSearchPath, querySuitePath, memoryFlag, threadsFlag) {
|
||||
const codeqlArgs = [
|
||||
async databaseAnalyze(databasePath, sarifFile, querySuite, memoryFlag, addSnippetsFlag, threadsFlag) {
|
||||
await new toolrunnner.ToolRunner(cmd, [
|
||||
"database",
|
||||
"run-queries",
|
||||
"analyze",
|
||||
memoryFlag,
|
||||
threadsFlag,
|
||||
databasePath,
|
||||
"--min-disk-free=1024",
|
||||
"-v",
|
||||
...getExtraOptionsFromEnv(["database", "run-queries"]),
|
||||
];
|
||||
if (extraSearchPath !== undefined) {
|
||||
codeqlArgs.push("--additional-packs", extraSearchPath);
|
||||
}
|
||||
codeqlArgs.push(querySuitePath);
|
||||
await runTool(cmd, codeqlArgs);
|
||||
},
|
||||
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, addSnippetsFlag, threadsFlag, automationDetailsId) {
|
||||
const codeqlArgs = [
|
||||
"database",
|
||||
"interpret-results",
|
||||
threadsFlag,
|
||||
"--format=sarif-latest",
|
||||
"--print-metrics-summary",
|
||||
"--sarif-group-rules-by-pack",
|
||||
"-v",
|
||||
`--output=${sarifFile}`,
|
||||
addSnippetsFlag,
|
||||
...getExtraOptionsFromEnv(["database", "interpret-results"]),
|
||||
];
|
||||
if (automationDetailsId !== undefined) {
|
||||
codeqlArgs.push("--sarif-category", automationDetailsId);
|
||||
}
|
||||
codeqlArgs.push(databasePath, ...querySuitePaths);
|
||||
// capture stdout, which contains analysis summaries
|
||||
return await runTool(cmd, codeqlArgs);
|
||||
},
|
||||
/**
|
||||
* Download specified packs into the package cache. If the specified
|
||||
* package and version already exists (e.g., from a previous analysis run),
|
||||
* then it is not downloaded again (unless the extra option `--force` is
|
||||
* specified).
|
||||
*
|
||||
* If no version is specified, then the latest version is
|
||||
* downloaded. The check to determine what the latest version is is done
|
||||
* each time this package is requested.
|
||||
*/
|
||||
async packDownload(packs) {
|
||||
const codeqlArgs = [
|
||||
"pack",
|
||||
"download",
|
||||
"--format=json",
|
||||
...getExtraOptionsFromEnv(["pack", "download"]),
|
||||
...packs.map(packWithVersionToString),
|
||||
];
|
||||
const output = await runTool(cmd, codeqlArgs);
|
||||
try {
|
||||
const parsedOutput = JSON.parse(output);
|
||||
if (Array.isArray(parsedOutput.packs) &&
|
||||
// TODO PackDownloadOutput will not include the version if it is not specified
|
||||
// in the input. The version is always the latest version available.
|
||||
// It should be added to the output, but this requires a CLI change
|
||||
parsedOutput.packs.every((p) => p.name /* && p.version */)) {
|
||||
return parsedOutput;
|
||||
}
|
||||
else {
|
||||
throw new Error("Unexpected output from pack download");
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Attempted to download specified packs but got an error:\n${output}\n${e}`);
|
||||
}
|
||||
},
|
||||
async databaseCleanup(databasePath, cleanupLevel) {
|
||||
const codeqlArgs = [
|
||||
"database",
|
||||
"cleanup",
|
||||
databasePath,
|
||||
`--mode=${cleanupLevel}`,
|
||||
];
|
||||
await runTool(cmd, codeqlArgs);
|
||||
},
|
||||
async databaseBundle(databasePath, outputFilePath) {
|
||||
const args = [
|
||||
"database",
|
||||
"bundle",
|
||||
databasePath,
|
||||
`--output=${outputFilePath}`,
|
||||
];
|
||||
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||
...getExtraOptionsFromEnv(["database", "analyze"]),
|
||||
querySuite,
|
||||
]).exec();
|
||||
},
|
||||
};
|
||||
}
|
||||
function packWithVersionToString(pack) {
|
||||
return pack.version ? `${pack.packName}@${pack.version}` : pack.packName;
|
||||
}
|
||||
/**
|
||||
* Gets the options for `path` of `options` as an array of extra option strings.
|
||||
*/
|
||||
function getExtraOptionsFromEnv(paths) {
|
||||
function getExtraOptionsFromEnv(path) {
|
||||
const options = util.getExtraOptionsEnvParam();
|
||||
return getExtraOptions(options, paths, []);
|
||||
}
|
||||
/**
|
||||
* Gets `options` as an array of extra option strings.
|
||||
*
|
||||
* - throws an exception mentioning `pathInfo` if this conversion is impossible.
|
||||
*/
|
||||
function asExtraOptions(options, pathInfo) {
|
||||
if (options === undefined) {
|
||||
return [];
|
||||
}
|
||||
if (!Array.isArray(options)) {
|
||||
const msg = `The extra options for '${pathInfo.join(".")}' ('${JSON.stringify(options)}') are not in an array.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return options.map((o) => {
|
||||
const t = typeof o;
|
||||
if (t !== "string" && t !== "number" && t !== "boolean") {
|
||||
const msg = `The extra option for '${pathInfo.join(".")}' ('${JSON.stringify(o)}') is not a primitive value.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return `${o}`;
|
||||
});
|
||||
return getExtraOptions(options, path, []);
|
||||
}
|
||||
/**
|
||||
* Gets the options for `path` of `options` as an array of extra option strings.
|
||||
*
|
||||
* - the special terminal step name '*' in `options` matches all path steps
|
||||
* - throws an exception if this conversion is impossible.
|
||||
*
|
||||
* Exported for testing.
|
||||
*/
|
||||
function getExtraOptions(options, paths, pathInfo) {
|
||||
function getExtraOptions(options, path, pathInfo) {
|
||||
var _a, _b, _c;
|
||||
/**
|
||||
* Gets `options` as an array of extra option strings.
|
||||
*
|
||||
* - throws an exception mentioning `pathInfo` if this conversion is impossible.
|
||||
*/
|
||||
function asExtraOptions(options, pathInfo) {
|
||||
if (options === undefined) {
|
||||
return [];
|
||||
}
|
||||
if (!Array.isArray(options)) {
|
||||
const msg = `The extra options for '${pathInfo.join(".")}' ('${JSON.stringify(options)}') are not in an array.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return options.map((o) => {
|
||||
const t = typeof o;
|
||||
if (t !== "string" && t !== "number" && t !== "boolean") {
|
||||
const msg = `The extra option for '${pathInfo.join(".")}' ('${JSON.stringify(o)}') is not a primitive value.`;
|
||||
throw new Error(msg);
|
||||
}
|
||||
return `${o}`;
|
||||
});
|
||||
}
|
||||
const all = asExtraOptions((_a = options) === null || _a === void 0 ? void 0 : _a["*"], pathInfo.concat("*"));
|
||||
const specific = paths.length === 0
|
||||
const specific = path.length === 0
|
||||
? asExtraOptions(options, pathInfo)
|
||||
: getExtraOptions((_b = options) === null || _b === void 0 ? void 0 : _b[paths[0]], (_c = paths) === null || _c === void 0 ? void 0 : _c.slice(1), pathInfo.concat(paths[0]));
|
||||
: getExtraOptions((_b = options) === null || _b === void 0 ? void 0 : _b[path[0]], (_c = path) === null || _c === void 0 ? void 0 : _c.slice(1), pathInfo.concat(path[0]));
|
||||
return all.concat(specific);
|
||||
}
|
||||
exports.getExtraOptions = getExtraOptions;
|
||||
/*
|
||||
* A constant defining the maximum number of characters we will keep from
|
||||
* the programs stderr for logging. This serves two purposes:
|
||||
* (1) It avoids an OOM if a program fails in a way that results it
|
||||
* printing many log lines.
|
||||
* (2) It avoids us hitting the limit of how much data we can send in our
|
||||
* status reports on GitHub.com.
|
||||
*/
|
||||
const maxErrorSize = 20000;
|
||||
async function runTool(cmd, args = []) {
|
||||
let output = "";
|
||||
let error = "";
|
||||
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
output += data.toString();
|
||||
},
|
||||
stderr: (data) => {
|
||||
const toRead = Math.min(maxErrorSize - error.length, data.length);
|
||||
error += data.toString("utf8", 0, toRead);
|
||||
},
|
||||
},
|
||||
ignoreReturnCode: true,
|
||||
}).exec();
|
||||
if (exitCode !== 0)
|
||||
throw new CommandInvocationError(cmd, args, exitCode, error);
|
||||
return output;
|
||||
}
|
||||
//# sourceMappingURL=codeql.js.map
|
||||
File diff suppressed because one or more lines are too long
137
lib/codeql.test.js
generated
137
lib/codeql.test.js
generated
@@ -10,146 +10,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path = __importStar(require("path"));
|
||||
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 codeql = __importStar(require("./codeql"));
|
||||
const defaults = __importStar(require("./defaults.json"));
|
||||
const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util = __importStar(require("./util"));
|
||||
const util_1 = require("./util");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
const sampleApiDetails = {
|
||||
auth: "token",
|
||||
url: "https://github.com",
|
||||
};
|
||||
const sampleGHAEApiDetails = {
|
||||
auth: "token",
|
||||
url: "https://example.githubenterprise.com",
|
||||
};
|
||||
ava_1.default.beforeEach(() => {
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
|
||||
});
|
||||
ava_1.default("download codeql bundle cache", async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
const versions = ["20200601", "20200610"];
|
||||
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`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
await codeql.setupCodeQL(`https://example.com/download/codeql-bundle-${version}/codeql-bundle.tar.gz`, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
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}`));
|
||||
}
|
||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||
t.is(cachedVersions.length, 2);
|
||||
});
|
||||
});
|
||||
ava_1.default("download codeql bundle cache explicitly requested with pinned different version cached", async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
nock_1.default("https://example.com")
|
||||
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
||||
nock_1.default("https://example.com")
|
||||
.get(`/download/codeql-bundle-20200610/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200610/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
|
||||
});
|
||||
});
|
||||
ava_1.default("don't download codeql bundle cache with pinned different version cached", async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
nock_1.default("https://example.com")
|
||||
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
||||
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||
t.is(cachedVersions.length, 1);
|
||||
});
|
||||
});
|
||||
ava_1.default("download codeql bundle cache with different version cached (not pinned)", async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
nock_1.default("https://example.com")
|
||||
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
||||
const platform = process.platform === "win32"
|
||||
? "win64"
|
||||
: process.platform === "linux"
|
||||
? "linux64"
|
||||
: "osx64";
|
||||
nock_1.default("https://github.com")
|
||||
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/codeql-bundle-${platform}.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||
t.is(cachedVersions.length, 2);
|
||||
});
|
||||
});
|
||||
ava_1.default('download codeql bundle cache with pinned different version cached if "latest" tools specified', async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
nock_1.default("https://example.com")
|
||||
.get(`/download/codeql-bundle-20200601/codeql-bundle.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||
await codeql.setupCodeQL("https://example.com/download/codeql-bundle-20200601/codeql-bundle.tar.gz", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
||||
const platform = process.platform === "win32"
|
||||
? "win64"
|
||||
: process.platform === "linux"
|
||||
? "linux64"
|
||||
: "osx64";
|
||||
nock_1.default("https://github.com")
|
||||
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/codeql-bundle-${platform}.tar.gz`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle.tar.gz`));
|
||||
await codeql.setupCodeQL("latest", sampleApiDetails, tmpDir, tmpDir, util.GitHubVariant.DOTCOM, logging_1.getRunnerLogger(true));
|
||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||
t.is(cachedVersions.length, 2);
|
||||
});
|
||||
});
|
||||
ava_1.default("download codeql bundle from github ae endpoint", async (t) => {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
const bundleAssetID = 10;
|
||||
const platform = process.platform === "win32"
|
||||
? "win64"
|
||||
: process.platform === "linux"
|
||||
? "linux64"
|
||||
: "osx64";
|
||||
const codeQLBundleName = `codeql-bundle-${platform}.tar.gz`;
|
||||
nock_1.default("https://example.githubenterprise.com")
|
||||
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/find/${defaults.bundleVersion}`)
|
||||
.reply(200, {
|
||||
assets: { [codeQLBundleName]: bundleAssetID },
|
||||
});
|
||||
nock_1.default("https://example.githubenterprise.com")
|
||||
.get(`/api/v3/enterprise/code-scanning/codeql-bundle/download/${bundleAssetID}`)
|
||||
.reply(200, {
|
||||
url: `https://example.githubenterprise.com/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`,
|
||||
});
|
||||
nock_1.default("https://example.githubenterprise.com")
|
||||
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`)
|
||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||
await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, tmpDir, util.GitHubVariant.GHAE, logging_1.getRunnerLogger(true));
|
||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||
t.is(cachedVersions.length, 1);
|
||||
});
|
||||
});
|
||||
ava_1.default("parse codeql bundle url version", (t) => {
|
||||
t.deepEqual(codeql.getCodeQLURLVersion("https://github.com/.../codeql-bundle-20200601/..."), "20200601");
|
||||
});
|
||||
ava_1.default("convert to semver", (t) => {
|
||||
const tests = {
|
||||
"20200601": "0.0.0-20200601",
|
||||
"20200601.0": "0.0.0-20200601.0",
|
||||
@@ -159,8 +44,9 @@ ava_1.default("convert to semver", (t) => {
|
||||
"1.2.3-beta.1": "1.2.3-beta.1",
|
||||
};
|
||||
for (const [version, expectedVersion] of Object.entries(tests)) {
|
||||
const url = `https://github.com/.../codeql-bundle-${version}/...`;
|
||||
try {
|
||||
const parsedVersion = codeql.convertToSemVer(version, logging_1.getRunnerLogger(true));
|
||||
const parsedVersion = codeql.getCodeQLURLVersion(url, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(parsedVersion, expectedVersion);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -190,19 +76,4 @@ ava_1.default("getExtraOptions throws for bad content", (t) => {
|
||||
t.throws(() => codeql.getExtraOptions({ foo: 87 }, ["foo"], []));
|
||||
t.throws(() => codeql.getExtraOptions({ "*": [42], foo: { "*": 87, bar: [99] } }, ["foo", "bar"], []));
|
||||
});
|
||||
ava_1.default("getCodeQLActionRepository", (t) => {
|
||||
const logger = logging_1.getRunnerLogger(true);
|
||||
util_1.initializeEnvironment(util_1.Mode.runner, "1.2.3");
|
||||
const repoActions = codeql.getCodeQLActionRepository(logger);
|
||||
t.deepEqual(repoActions, "github/codeql-action");
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
|
||||
// isRunningLocalAction() === true
|
||||
delete process.env["GITHUB_ACTION_REPOSITORY"];
|
||||
process.env["RUNNER_TEMP"] = path.dirname(__dirname);
|
||||
const repoLocalRunner = codeql.getCodeQLActionRepository(logger);
|
||||
t.deepEqual(repoLocalRunner, "github/codeql-action");
|
||||
process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy";
|
||||
const repoEnv = codeql.getCodeQLActionRepository(logger);
|
||||
t.deepEqual(repoEnv, "xxx/yyy");
|
||||
});
|
||||
//# sourceMappingURL=codeql.test.js.map
|
||||
File diff suppressed because one or more lines are too long
289
lib/config-utils.js
generated
289
lib/config-utils.js
generated
@@ -8,9 +8,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const yaml = __importStar(require("js-yaml"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const path = __importStar(require("path"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const externalQueries = __importStar(require("./external-queries"));
|
||||
const languages_1 = require("./languages");
|
||||
@@ -21,7 +20,6 @@ const QUERIES_PROPERTY = "queries";
|
||||
const QUERIES_USES_PROPERTY = "uses";
|
||||
const PATHS_IGNORE_PROPERTY = "paths-ignore";
|
||||
const PATHS_PROPERTY = "paths";
|
||||
const PACKS_PROPERTY = "packs";
|
||||
/**
|
||||
* A list of queries from https://github.com/github/codeql that
|
||||
* we don't want to run. Disabling them here is a quicker alternative to
|
||||
@@ -80,10 +78,7 @@ async function runResolveQueries(codeQL, resultMap, toResolve, extraSearchPath)
|
||||
}
|
||||
const queries = Object.keys(queryPaths).filter((q) => !queryIsDisabled(language, q));
|
||||
if (extraSearchPath !== undefined) {
|
||||
resultMap[language].custom.push({
|
||||
searchPath: extraSearchPath,
|
||||
queries,
|
||||
});
|
||||
resultMap[language].custom.push(...queries);
|
||||
}
|
||||
else {
|
||||
resultMap[language].builtin.push(...queries);
|
||||
@@ -104,8 +99,8 @@ const builtinSuites = ["security-extended", "security-and-quality"];
|
||||
* Throws an error if suiteName is not a valid builtin suite.
|
||||
*/
|
||||
async function addBuiltinSuiteQueries(languages, codeQL, resultMap, suiteName, configFile) {
|
||||
const found = builtinSuites.find((suite) => suite === suiteName);
|
||||
if (!found) {
|
||||
const suite = builtinSuites.find((suite) => suite === suiteName);
|
||||
if (!suite) {
|
||||
throw new Error(getQueryUsesInvalid(configFile, suiteName));
|
||||
}
|
||||
const suites = languages.map((l) => `${l}-${suiteName}.qls`);
|
||||
@@ -133,7 +128,7 @@ async function addLocalQueries(codeQL, resultMap, localQueryPath, checkoutPath,
|
||||
/**
|
||||
* Retrieve the set of queries at the referenced remote repo and add them to resultMap.
|
||||
*/
|
||||
async function addRemoteQueries(codeQL, resultMap, queryUses, tempDir, apiDetails, logger, configFile) {
|
||||
async function addRemoteQueries(codeQL, resultMap, queryUses, tempDir, githubUrl, logger, configFile) {
|
||||
let tok = queryUses.split("@");
|
||||
if (tok.length !== 2) {
|
||||
throw new Error(getQueryUsesInvalid(configFile, queryUses));
|
||||
@@ -152,7 +147,7 @@ async function addRemoteQueries(codeQL, resultMap, queryUses, tempDir, apiDetail
|
||||
}
|
||||
const nwo = `${tok[0]}/${tok[1]}`;
|
||||
// Checkout the external repository
|
||||
const checkoutPath = await externalQueries.checkoutExternalRepository(nwo, ref, apiDetails, tempDir, logger);
|
||||
const checkoutPath = await externalQueries.checkoutExternalRepository(nwo, ref, githubUrl, tempDir, logger);
|
||||
const queryPath = tok.length > 2
|
||||
? path.join(checkoutPath, tok.slice(2).join("/"))
|
||||
: checkoutPath;
|
||||
@@ -166,7 +161,7 @@ async function addRemoteQueries(codeQL, resultMap, queryUses, tempDir, apiDetail
|
||||
* local paths starting with './', or references to remote repos, or
|
||||
* a finite set of hardcoded terms for builtin suites.
|
||||
*/
|
||||
async function parseQueryUses(languages, codeQL, resultMap, queryUses, tempDir, checkoutPath, apiDetails, logger, configFile) {
|
||||
async function parseQueryUses(languages, codeQL, resultMap, queryUses, tempDir, checkoutPath, githubUrl, logger, configFile) {
|
||||
queryUses = queryUses.trim();
|
||||
if (queryUses === "") {
|
||||
throw new Error(getQueryUsesInvalid(configFile));
|
||||
@@ -182,7 +177,7 @@ async function parseQueryUses(languages, codeQL, resultMap, queryUses, tempDir,
|
||||
return;
|
||||
}
|
||||
// Otherwise, must be a reference to another repo
|
||||
await addRemoteQueries(codeQL, resultMap, queryUses, tempDir, apiDetails, logger, configFile);
|
||||
await addRemoteQueries(codeQL, resultMap, queryUses, tempDir, githubUrl, logger, configFile);
|
||||
}
|
||||
// Regex validating stars in paths or paths-ignore entries.
|
||||
// The intention is to only allow ** to appear when immediately
|
||||
@@ -190,44 +185,44 @@ async function parseQueryUses(languages, codeQL, resultMap, queryUses, tempDir,
|
||||
const pathStarsRegex = /.*(?:\*\*[^/].*|\*\*$|[^/]\*\*.*)/;
|
||||
// Characters that are supported by filters in workflows, but not by us.
|
||||
// See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
|
||||
const filterPatternCharactersRegex = /.*[?+[\]!].*/;
|
||||
const filterPatternCharactersRegex = /.*[\?\+\[\]!].*/;
|
||||
// Checks that a paths of paths-ignore entry is valid, possibly modifying it
|
||||
// to make it valid, or if not possible then throws an error.
|
||||
function validateAndSanitisePath(originalPath, propertyName, configFile, logger) {
|
||||
// Take a copy so we don't modify the original path, so we can still construct error messages
|
||||
let newPath = originalPath;
|
||||
let path = originalPath;
|
||||
// All paths are relative to the src root, so strip off leading slashes.
|
||||
while (newPath.charAt(0) === "/") {
|
||||
newPath = newPath.substring(1);
|
||||
while (path.charAt(0) === "/") {
|
||||
path = path.substring(1);
|
||||
}
|
||||
// Trailing ** are redundant, so strip them off
|
||||
if (newPath.endsWith("/**")) {
|
||||
newPath = newPath.substring(0, newPath.length - 2);
|
||||
if (path.endsWith("/**")) {
|
||||
path = path.substring(0, path.length - 2);
|
||||
}
|
||||
// An empty path is not allowed as it's meaningless
|
||||
if (newPath === "") {
|
||||
if (path === "") {
|
||||
throw new Error(getConfigFilePropertyError(configFile, propertyName, `"${originalPath}" is not an invalid path. ` +
|
||||
`It is not necessary to include it, and it is not allowed to exclude it.`));
|
||||
}
|
||||
// Check for illegal uses of **
|
||||
if (newPath.match(pathStarsRegex)) {
|
||||
if (path.match(pathStarsRegex)) {
|
||||
throw new Error(getConfigFilePropertyError(configFile, propertyName, `"${originalPath}" contains an invalid "**" wildcard. ` +
|
||||
`They must be immediately preceded and followed by a slash as in "/**/", or come at the start or end.`));
|
||||
`They must be immediately preceeded and followed by a slash as in "/**/", or come at the start or end.`));
|
||||
}
|
||||
// Check for other regex characters that we don't support.
|
||||
// Output a warning so the user knows, but otherwise continue normally.
|
||||
if (newPath.match(filterPatternCharactersRegex)) {
|
||||
if (path.match(filterPatternCharactersRegex)) {
|
||||
logger.warning(getConfigFilePropertyError(configFile, propertyName, `"${originalPath}" contains an unsupported character. ` +
|
||||
`The filter pattern characters ?, +, [, ], ! are not supported and will be matched literally.`));
|
||||
}
|
||||
// Ban any uses of backslash for now.
|
||||
// This may not play nicely with project layouts.
|
||||
// This restriction can be lifted later if we determine they are ok.
|
||||
if (newPath.indexOf("\\") !== -1) {
|
||||
if (path.indexOf("\\") !== -1) {
|
||||
throw new Error(getConfigFilePropertyError(configFile, propertyName, `"${originalPath}" contains an "\\" character. These are not allowed in filters. ` +
|
||||
`If running on windows we recommend using "/" instead for path filters.`));
|
||||
}
|
||||
return newPath;
|
||||
return path;
|
||||
}
|
||||
exports.validateAndSanitisePath = validateAndSanitisePath;
|
||||
// An undefined configFile in some of these functions indicates that
|
||||
@@ -256,24 +251,6 @@ function getPathsInvalid(configFile) {
|
||||
return getConfigFilePropertyError(configFile, PATHS_PROPERTY, "must be an array of non-empty strings");
|
||||
}
|
||||
exports.getPathsInvalid = getPathsInvalid;
|
||||
function getPacksRequireLanguage(lang, configFile) {
|
||||
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, `has "${lang}", but it is not one of the languages to analyze`);
|
||||
}
|
||||
exports.getPacksRequireLanguage = getPacksRequireLanguage;
|
||||
function getPacksInvalidSplit(configFile) {
|
||||
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, "must split packages by language");
|
||||
}
|
||||
exports.getPacksInvalidSplit = getPacksInvalidSplit;
|
||||
function getPacksInvalid(configFile) {
|
||||
return getConfigFilePropertyError(configFile, PACKS_PROPERTY, "must be an array of non-empty strings");
|
||||
}
|
||||
exports.getPacksInvalid = getPacksInvalid;
|
||||
function getPacksStrInvalid(packStr, configFile) {
|
||||
return configFile
|
||||
? getConfigFilePropertyError(configFile, PACKS_PROPERTY, `"${packStr}" is not a valid pack`)
|
||||
: `"${packStr}" is not a valid pack`;
|
||||
}
|
||||
exports.getPacksStrInvalid = getPacksStrInvalid;
|
||||
function getLocalPathOutsideOfRepository(configFile, localPath) {
|
||||
return getConfigFilePropertyError(configFile, `${QUERIES_PROPERTY}.${QUERIES_USES_PROPERTY}`, `is invalid as the local path "${localPath}" is outside of the repository`);
|
||||
}
|
||||
@@ -324,9 +301,11 @@ exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
||||
/**
|
||||
* Gets the set of languages in the current repository
|
||||
*/
|
||||
async function getLanguagesInRepo(repository, apiDetails, logger) {
|
||||
async function getLanguagesInRepo(repository, githubAuth, githubUrl, logger) {
|
||||
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
||||
const response = await api.getApiClient(apiDetails).repos.listLanguages({
|
||||
const response = await api
|
||||
.getApiClient(githubAuth, githubUrl, true)
|
||||
.repos.listLanguages({
|
||||
owner: repository.owner,
|
||||
repo: repository.repo,
|
||||
});
|
||||
@@ -354,7 +333,7 @@ async function getLanguagesInRepo(repository, apiDetails, logger) {
|
||||
* If no languages could be detected from either the workflow or the repository
|
||||
* then throw an error.
|
||||
*/
|
||||
async function getLanguages(codeQL, languagesInput, repository, apiDetails, logger) {
|
||||
async function getLanguages(languagesInput, repository, githubAuth, githubUrl, logger) {
|
||||
// Obtain from action input 'languages' if set
|
||||
let languages = (languagesInput || "")
|
||||
.split(",")
|
||||
@@ -363,9 +342,7 @@ async function getLanguages(codeQL, languagesInput, repository, apiDetails, logg
|
||||
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, apiDetails, logger);
|
||||
const availableLanguages = await codeQL.resolveLanguages();
|
||||
languages = languages.filter((value) => value in availableLanguages);
|
||||
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
|
||||
@@ -390,12 +367,12 @@ async function getLanguages(codeQL, languagesInput, repository, apiDetails, logg
|
||||
}
|
||||
return parsedLanguages;
|
||||
}
|
||||
async function addQueriesFromWorkflow(codeQL, queriesInput, languages, resultMap, tempDir, checkoutPath, apiDetails, logger) {
|
||||
async function addQueriesFromWorkflow(codeQL, queriesInput, languages, resultMap, tempDir, checkoutPath, githubUrl, logger) {
|
||||
queriesInput = queriesInput.trim();
|
||||
// "+" means "don't override config file" - see shouldAddConfigFileQueries
|
||||
queriesInput = queriesInput.replace(/^\+/, "");
|
||||
for (const query of queriesInput.split(",")) {
|
||||
await parseQueryUses(languages, codeQL, resultMap, query, tempDir, checkoutPath, apiDetails, logger);
|
||||
await parseQueryUses(languages, codeQL, resultMap, query, tempDir, checkoutPath, githubUrl, logger);
|
||||
}
|
||||
}
|
||||
// Returns true if either no queries were provided in the workflow.
|
||||
@@ -411,41 +388,29 @@ function shouldAddConfigFileQueries(queriesInput) {
|
||||
/**
|
||||
* Get the default config for when the user has not supplied one.
|
||||
*/
|
||||
async function getDefaultConfig(languagesInput, queriesInput, packsInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
|
||||
var _a;
|
||||
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
|
||||
async function getDefaultConfig(languagesInput, queriesInput, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
|
||||
const queries = {};
|
||||
for (const language of languages) {
|
||||
queries[language] = {
|
||||
builtin: [],
|
||||
custom: [],
|
||||
};
|
||||
}
|
||||
await addDefaultQueries(codeQL, languages, queries);
|
||||
if (queriesInput) {
|
||||
await addQueriesFromWorkflow(codeQL, queriesInput, languages, queries, tempDir, checkoutPath, apiDetails, logger);
|
||||
await addQueriesFromWorkflow(codeQL, queriesInput, languages, queries, tempDir, checkoutPath, githubUrl, logger);
|
||||
}
|
||||
const packs = (_a = parsePacksFromInput(packsInput, languages), (_a !== null && _a !== void 0 ? _a : {}));
|
||||
return {
|
||||
languages,
|
||||
queries,
|
||||
pathsIgnore: [],
|
||||
paths: [],
|
||||
packs,
|
||||
originalUserInput: {},
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
|
||||
};
|
||||
}
|
||||
exports.getDefaultConfig = getDefaultConfig;
|
||||
/**
|
||||
* Load the config from the given file.
|
||||
*/
|
||||
async function loadConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
|
||||
var _a;
|
||||
async function loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||
let parsedYAML;
|
||||
if (isLocal(configFile)) {
|
||||
// Treat the config file as relative to the workspace
|
||||
@@ -453,7 +418,7 @@ async function loadConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||
parsedYAML = getLocalConfig(configFile, checkoutPath);
|
||||
}
|
||||
else {
|
||||
parsedYAML = await getRemoteConfig(configFile, apiDetails);
|
||||
parsedYAML = await getRemoteConfig(configFile, githubAuth, githubUrl);
|
||||
}
|
||||
// Validate that the 'name' property is syntactically correct,
|
||||
// even though we don't use the value yet.
|
||||
@@ -465,14 +430,8 @@ async function loadConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||
throw new Error(getNameInvalid(configFile));
|
||||
}
|
||||
}
|
||||
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
|
||||
const languages = await getLanguages(languagesInput, repository, githubAuth, githubUrl, logger);
|
||||
const queries = {};
|
||||
for (const language of languages) {
|
||||
queries[language] = {
|
||||
builtin: [],
|
||||
custom: [],
|
||||
};
|
||||
}
|
||||
const pathsIgnore = [];
|
||||
const paths = [];
|
||||
let disableDefaultQueries = false;
|
||||
@@ -490,205 +449,79 @@ async function loadConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||
// unless they're prefixed with "+", in which case they supplement those
|
||||
// in the config file.
|
||||
if (queriesInput) {
|
||||
await addQueriesFromWorkflow(codeQL, queriesInput, languages, queries, tempDir, checkoutPath, apiDetails, logger);
|
||||
await addQueriesFromWorkflow(codeQL, queriesInput, languages, queries, tempDir, checkoutPath, githubUrl, logger);
|
||||
}
|
||||
if (shouldAddConfigFileQueries(queriesInput) &&
|
||||
QUERIES_PROPERTY in parsedYAML) {
|
||||
const queriesArr = parsedYAML[QUERIES_PROPERTY];
|
||||
if (!Array.isArray(queriesArr)) {
|
||||
if (!(parsedYAML[QUERIES_PROPERTY] instanceof Array)) {
|
||||
throw new Error(getQueriesInvalid(configFile));
|
||||
}
|
||||
for (const query of queriesArr) {
|
||||
for (const query of parsedYAML[QUERIES_PROPERTY]) {
|
||||
if (!(QUERIES_USES_PROPERTY in query) ||
|
||||
typeof query[QUERIES_USES_PROPERTY] !== "string") {
|
||||
throw new Error(getQueryUsesInvalid(configFile));
|
||||
}
|
||||
await parseQueryUses(languages, codeQL, queries, query[QUERIES_USES_PROPERTY], tempDir, checkoutPath, apiDetails, logger, configFile);
|
||||
await parseQueryUses(languages, codeQL, queries, query[QUERIES_USES_PROPERTY], tempDir, checkoutPath, githubUrl, logger, configFile);
|
||||
}
|
||||
}
|
||||
if (PATHS_IGNORE_PROPERTY in parsedYAML) {
|
||||
if (!Array.isArray(parsedYAML[PATHS_IGNORE_PROPERTY])) {
|
||||
if (!(parsedYAML[PATHS_IGNORE_PROPERTY] instanceof Array)) {
|
||||
throw new Error(getPathsIgnoreInvalid(configFile));
|
||||
}
|
||||
for (const ignorePath of parsedYAML[PATHS_IGNORE_PROPERTY]) {
|
||||
if (typeof ignorePath !== "string" || ignorePath === "") {
|
||||
for (const path of parsedYAML[PATHS_IGNORE_PROPERTY]) {
|
||||
if (typeof path !== "string" || path === "") {
|
||||
throw new Error(getPathsIgnoreInvalid(configFile));
|
||||
}
|
||||
pathsIgnore.push(validateAndSanitisePath(ignorePath, PATHS_IGNORE_PROPERTY, configFile, logger));
|
||||
pathsIgnore.push(validateAndSanitisePath(path, PATHS_IGNORE_PROPERTY, configFile, logger));
|
||||
}
|
||||
}
|
||||
if (PATHS_PROPERTY in parsedYAML) {
|
||||
if (!Array.isArray(parsedYAML[PATHS_PROPERTY])) {
|
||||
if (!(parsedYAML[PATHS_PROPERTY] instanceof Array)) {
|
||||
throw new Error(getPathsInvalid(configFile));
|
||||
}
|
||||
for (const includePath of parsedYAML[PATHS_PROPERTY]) {
|
||||
if (typeof includePath !== "string" || includePath === "") {
|
||||
for (const path of parsedYAML[PATHS_PROPERTY]) {
|
||||
if (typeof path !== "string" || path === "") {
|
||||
throw new Error(getPathsInvalid(configFile));
|
||||
}
|
||||
paths.push(validateAndSanitisePath(includePath, PATHS_PROPERTY, configFile, logger));
|
||||
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.
|
||||
for (const language of languages) {
|
||||
if (queries[language] === undefined ||
|
||||
(queries[language].builtin.length === 0 &&
|
||||
queries[language].custom.length === 0)) {
|
||||
throw new Error(`Did not detect any queries to run for ${language}. ` +
|
||||
"Please make sure that the default queries are enabled, or you are specifying queries to run.");
|
||||
}
|
||||
}
|
||||
const packs = parsePacks((_a = parsedYAML[PACKS_PROPERTY], (_a !== null && _a !== void 0 ? _a : {})), packsInput, languages, configFile);
|
||||
return {
|
||||
languages,
|
||||
queries,
|
||||
pathsIgnore,
|
||||
paths,
|
||||
packs,
|
||||
originalUserInput: parsedYAML,
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
dbLocation: dbLocationOrDefault(dbLocation, tempDir),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
|
||||
* and `-` allowed as long as not the first or last char.
|
||||
**/
|
||||
const PACK_IDENTIFIER_PATTERN = (function () {
|
||||
const alphaNumeric = "[a-z0-9]";
|
||||
const alphaNumericDash = "[a-z0-9-]";
|
||||
const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`;
|
||||
return new RegExp(`^${component}/${component}$`);
|
||||
})();
|
||||
// Exported for testing
|
||||
function parsePacksFromConfig(packsByLanguage, languages, configFile) {
|
||||
const packs = {};
|
||||
if (Array.isArray(packsByLanguage)) {
|
||||
if (languages.length === 1) {
|
||||
// single language analysis, so language is implicit
|
||||
packsByLanguage = {
|
||||
[languages[0]]: packsByLanguage,
|
||||
};
|
||||
}
|
||||
else {
|
||||
// this is an error since multi-language analysis requires
|
||||
// packs split by language
|
||||
throw new Error(getPacksInvalidSplit(configFile));
|
||||
}
|
||||
}
|
||||
for (const [lang, packsArr] of Object.entries(packsByLanguage)) {
|
||||
if (!Array.isArray(packsArr)) {
|
||||
throw new Error(getPacksInvalid(configFile));
|
||||
}
|
||||
if (!languages.includes(lang)) {
|
||||
throw new Error(getPacksRequireLanguage(lang, configFile));
|
||||
}
|
||||
packs[lang] = [];
|
||||
for (const packStr of packsArr) {
|
||||
packs[lang].push(toPackWithVersion(packStr, configFile));
|
||||
}
|
||||
}
|
||||
return packs;
|
||||
}
|
||||
exports.parsePacksFromConfig = parsePacksFromConfig;
|
||||
function parsePacksFromInput(packsInput, languages) {
|
||||
var _a;
|
||||
if (!((_a = packsInput) === null || _a === void 0 ? void 0 : _a.trim())) {
|
||||
return undefined;
|
||||
}
|
||||
if (languages.length > 1) {
|
||||
throw new Error("Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.");
|
||||
}
|
||||
else if (languages.length === 0) {
|
||||
throw new Error("No languages specified. Cannot process the packs input.");
|
||||
}
|
||||
packsInput = packsInput.trim();
|
||||
if (packsInput.startsWith("+")) {
|
||||
packsInput = packsInput.substring(1).trim();
|
||||
if (!packsInput) {
|
||||
throw new Error("A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.");
|
||||
}
|
||||
}
|
||||
return {
|
||||
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
|
||||
packs.push(toPackWithVersion(pack, ""));
|
||||
return packs;
|
||||
}, []),
|
||||
};
|
||||
}
|
||||
function toPackWithVersion(packStr, configFile) {
|
||||
if (typeof packStr !== "string") {
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
const nameWithVersion = packStr.trim().split("@");
|
||||
let version;
|
||||
if (nameWithVersion.length > 2 ||
|
||||
!PACK_IDENTIFIER_PATTERN.test(nameWithVersion[0])) {
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
else if (nameWithVersion.length === 2) {
|
||||
version = semver.clean(nameWithVersion[1]) || undefined;
|
||||
if (!version) {
|
||||
throw new Error(getPacksStrInvalid(packStr, configFile));
|
||||
}
|
||||
}
|
||||
return {
|
||||
packName: nameWithVersion[0].trim(),
|
||||
version,
|
||||
};
|
||||
}
|
||||
// exported for testing
|
||||
function parsePacks(rawPacksFromConfig, rawPacksInput, languages, configFile) {
|
||||
const packsFromInput = parsePacksFromInput(rawPacksInput, languages);
|
||||
const packsFomConfig = parsePacksFromConfig(rawPacksFromConfig, languages, configFile);
|
||||
if (!packsFromInput) {
|
||||
return packsFomConfig;
|
||||
}
|
||||
if (!shouldCombinePacks(rawPacksInput)) {
|
||||
return packsFromInput;
|
||||
}
|
||||
return combinePacks(packsFromInput, packsFomConfig);
|
||||
}
|
||||
exports.parsePacks = parsePacks;
|
||||
function shouldCombinePacks(packsInput) {
|
||||
var _a;
|
||||
return !!((_a = packsInput) === null || _a === void 0 ? void 0 : _a.trim().startsWith("+"));
|
||||
}
|
||||
function combinePacks(packs1, packs2) {
|
||||
const packs = {};
|
||||
for (const lang of Object.keys(packs1)) {
|
||||
packs[lang] = packs1[lang].concat(packs2[lang] || []);
|
||||
}
|
||||
for (const lang of Object.keys(packs2)) {
|
||||
if (!packs[lang]) {
|
||||
packs[lang] = packs2[lang];
|
||||
}
|
||||
}
|
||||
return packs;
|
||||
}
|
||||
function dbLocationOrDefault(dbLocation, tempDir) {
|
||||
return dbLocation || path.resolve(tempDir, "codeql_databases");
|
||||
}
|
||||
/**
|
||||
* Load and return the config.
|
||||
*
|
||||
* 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, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
|
||||
var _a, _b, _c;
|
||||
async function initConfig(languagesInput, queriesInput, configFile, repository, 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, packsInput, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
|
||||
config = await getDefaultConfig(languagesInput, queriesInput, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
||||
}
|
||||
else {
|
||||
config = await loadConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
|
||||
}
|
||||
// The list of queries should not be empty for any language. If it is then
|
||||
// it is a user configuration error.
|
||||
for (const language of config.languages) {
|
||||
const hasBuiltinQueries = ((_a = config.queries[language]) === null || _a === void 0 ? void 0 : _a.builtin.length) > 0;
|
||||
const hasCustomQueries = ((_b = config.queries[language]) === null || _b === void 0 ? void 0 : _b.custom.length) > 0;
|
||||
const hasPacks = (((_c = config.packs[language]) === null || _c === void 0 ? void 0 : _c.length) || 0) > 0;
|
||||
if (!hasPacks && !hasBuiltinQueries && !hasCustomQueries) {
|
||||
throw new Error(`Did not detect any queries to run for ${language}. ` +
|
||||
"Please make sure that the default queries are enabled, or you are specifying queries to run.");
|
||||
}
|
||||
config = await loadConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
||||
}
|
||||
// Save the config so we can easily access it again in the future
|
||||
await saveConfig(config, logger);
|
||||
@@ -713,7 +546,7 @@ function getLocalConfig(configFile, checkoutPath) {
|
||||
}
|
||||
return yaml.safeLoad(fs.readFileSync(configFile, "utf8"));
|
||||
}
|
||||
async function getRemoteConfig(configFile, apiDetails) {
|
||||
async function getRemoteConfig(configFile, githubAuth, githubUrl) {
|
||||
// retrieve the various parts of the config location, and ensure they're present
|
||||
const format = new RegExp("(?<owner>[^/]+)/(?<repo>[^/]+)/(?<path>[^@]+)@(?<ref>.*)");
|
||||
const pieces = format.exec(configFile);
|
||||
@@ -722,7 +555,7 @@ async function getRemoteConfig(configFile, apiDetails) {
|
||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||
}
|
||||
const response = await api
|
||||
.getApiClient(apiDetails, { allowExternal: true })
|
||||
.getApiClient(githubAuth, githubUrl, true)
|
||||
.repos.getContent({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
|
||||
File diff suppressed because one or more lines are too long
326
lib/config-utils.test.js
generated
326
lib/config-utils.test.js
generated
@@ -10,11 +10,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const github = __importStar(require("@actions/github"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const semver_1 = require("semver");
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const sinon_1 = __importDefault(require("sinon"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const codeql_1 = require("./codeql");
|
||||
@@ -24,12 +23,6 @@ const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util = __importStar(require("./util"));
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
const sampleApiDetails = {
|
||||
auth: "token",
|
||||
externalRepoAuth: "token",
|
||||
url: "https://github.example.com",
|
||||
};
|
||||
const gitHubVersion = { type: util.GitHubVariant.DOTCOM };
|
||||
// Returns the filepath of the newly-created file
|
||||
function createConfigFile(inputFileContents, tmpDir) {
|
||||
const configFilePath = path.join(tmpDir, "input");
|
||||
@@ -67,17 +60,14 @@ ava_1.default("load empty config", async (t) => {
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
javascript: { queries: ["query1.ql"] },
|
||||
python: { queries: ["query2.ql"] },
|
||||
},
|
||||
byLanguage: {},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
|
||||
t.deepEqual(config, await configUtils.getDefaultConfig(languages, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger));
|
||||
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));
|
||||
});
|
||||
});
|
||||
ava_1.default("loading config saves config", async (t) => {
|
||||
@@ -86,10 +76,7 @@ ava_1.default("loading config saves config", async (t) => {
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
javascript: { queries: ["query1.ql"] },
|
||||
python: { queries: ["query2.ql"] },
|
||||
},
|
||||
byLanguage: {},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
@@ -99,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, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logger);
|
||||
const config1 = await configUtils.initConfig("javascript,python", undefined, undefined, { owner: "github", repo: "example " }, 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
|
||||
@@ -110,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, undefined, "../input", undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -123,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, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -137,7 +124,7 @@ ava_1.default("load non-existent input", async (t) => {
|
||||
const configFile = "input";
|
||||
t.false(fs.existsSync(path.join(tmpDir, configFile)));
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -179,12 +166,7 @@ ava_1.default("load non-empty input", async (t) => {
|
||||
queries: {
|
||||
javascript: {
|
||||
builtin: [],
|
||||
custom: [
|
||||
{
|
||||
queries: ["/foo/a.ql", "/bar/b.ql"],
|
||||
searchPath: tmpDir,
|
||||
},
|
||||
],
|
||||
custom: ["/foo/a.ql", "/bar/b.ql"],
|
||||
},
|
||||
},
|
||||
pathsIgnore: ["a", "b"],
|
||||
@@ -199,13 +181,10 @@ ava_1.default("load non-empty input", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
gitHubVersion,
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
packs: {},
|
||||
};
|
||||
const languages = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
const actualConfig = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// Should exactly equal the object we constructed earlier
|
||||
t.deepEqual(actualConfig, expectedConfig);
|
||||
});
|
||||
@@ -234,14 +213,14 @@ ava_1.default("Default queries are used", async (t) => {
|
||||
});
|
||||
// The important point of this config is that it doesn't specify
|
||||
// the disable-default-queries field.
|
||||
// Any other details are hopefully irrelevant for this test.
|
||||
// Any other details are hopefully irrelevant for this tetst.
|
||||
const inputFileContents = `
|
||||
paths:
|
||||
- foo`;
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
const languages = "javascript";
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
await configUtils.initConfig(languages, undefined, configFilePath, { owner: "github", repo: "example " }, 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, [
|
||||
@@ -284,7 +263,7 @@ ava_1.default("Queries can be specified in config file", async (t) => {
|
||||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, undefined, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries
|
||||
// and once for `./foo` from the config file.
|
||||
@@ -295,7 +274,7 @@ ava_1.default("Queries can be specified in config file", async (t) => {
|
||||
t.deepEqual(config.queries["javascript"].builtin.length, 1);
|
||||
t.deepEqual(config.queries["javascript"].custom.length, 1);
|
||||
t.regex(config.queries["javascript"].builtin[0], /javascript-code-scanning.qls$/);
|
||||
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/foo$/);
|
||||
t.regex(config.queries["javascript"].custom[0], /.*\/foo$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("Queries from config file can be overridden in workflow file", async (t) => {
|
||||
@@ -306,7 +285,7 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
|
||||
- uses: ./foo`;
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
// This config item should take precedence over the config file but shouldn't affect the default queries.
|
||||
const testQueries = "./override";
|
||||
const queries = "./override";
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
fs.mkdirSync(path.join(tmpDir, "override"));
|
||||
const resolveQueriesArgs = [];
|
||||
@@ -317,7 +296,7 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
|
||||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// 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.
|
||||
@@ -328,7 +307,7 @@ ava_1.default("Queries from config file can be overridden in workflow file", asy
|
||||
t.deepEqual(config.queries["javascript"].builtin.length, 1);
|
||||
t.deepEqual(config.queries["javascript"].custom.length, 1);
|
||||
t.regex(config.queries["javascript"].builtin[0], /javascript-code-scanning.qls$/);
|
||||
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/override$/);
|
||||
t.regex(config.queries["javascript"].custom[0], /.*\/override$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("Queries in workflow file can be used in tandem with the 'disable default queries' option", async (t) => {
|
||||
@@ -339,7 +318,7 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
|
||||
name: my config
|
||||
disable-default-queries: true`;
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
const testQueries = "./workflow-query";
|
||||
const queries = "./workflow-query";
|
||||
fs.mkdirSync(path.join(tmpDir, "workflow-query"));
|
||||
const resolveQueriesArgs = [];
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
@@ -349,7 +328,7 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
|
||||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// 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
|
||||
@@ -359,14 +338,14 @@ ava_1.default("Queries in workflow file can be used in tandem with the 'disable
|
||||
// Now check that the end result contains only the workflow query, and not the default one
|
||||
t.deepEqual(config.queries["javascript"].builtin.length, 0);
|
||||
t.deepEqual(config.queries["javascript"].custom.length, 1);
|
||||
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/workflow-query$/);
|
||||
t.regex(config.queries["javascript"].custom[0], /.*\/workflow-query$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("Multiple queries can be specified in workflow file, no config file required", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
fs.mkdirSync(path.join(tmpDir, "override1"));
|
||||
fs.mkdirSync(path.join(tmpDir, "override2"));
|
||||
const testQueries = "./override1,./override2";
|
||||
const queries = "./override1,./override2";
|
||||
const resolveQueriesArgs = [];
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveQueries(queries, extraSearchPath) {
|
||||
@@ -375,7 +354,7 @@ ava_1.default("Multiple queries can be specified in workflow file, no config fil
|
||||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// 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
|
||||
@@ -388,8 +367,8 @@ ava_1.default("Multiple queries can be specified in workflow file, no config fil
|
||||
t.deepEqual(config.queries["javascript"].builtin.length, 1);
|
||||
t.deepEqual(config.queries["javascript"].custom.length, 2);
|
||||
t.regex(config.queries["javascript"].builtin[0], /javascript-code-scanning.qls$/);
|
||||
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/override1$/);
|
||||
t.regex(config.queries["javascript"].custom[1].queries[0], /.*\/override2$/);
|
||||
t.regex(config.queries["javascript"].custom[0], /.*\/override1$/);
|
||||
t.regex(config.queries["javascript"].custom[1], /.*\/override2$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("Queries in workflow file can be added to the set of queries without overriding config file", async (t) => {
|
||||
@@ -402,7 +381,7 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
|
||||
- uses: ./foo`;
|
||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||
// These queries shouldn't override anything, because the value is prefixed with "+"
|
||||
const testQueries = "+./additional1,./additional2";
|
||||
const queries = "+./additional1,./additional2";
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
fs.mkdirSync(path.join(tmpDir, "additional1"));
|
||||
fs.mkdirSync(path.join(tmpDir, "additional2"));
|
||||
@@ -414,7 +393,7 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
|
||||
},
|
||||
});
|
||||
const languages = "javascript";
|
||||
const config = await configUtils.initConfig(languages, testQueries, undefined, configFilePath, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
// Check resolveQueries was called correctly
|
||||
// It'll be called once for the default queries,
|
||||
// once for each of additional1 and additional2,
|
||||
@@ -430,9 +409,9 @@ ava_1.default("Queries in workflow file can be added to the set of queries witho
|
||||
t.deepEqual(config.queries["javascript"].builtin.length, 1);
|
||||
t.deepEqual(config.queries["javascript"].custom.length, 3);
|
||||
t.regex(config.queries["javascript"].builtin[0], /javascript-code-scanning.qls$/);
|
||||
t.regex(config.queries["javascript"].custom[0].queries[0], /.*\/additional1$/);
|
||||
t.regex(config.queries["javascript"].custom[1].queries[0], /.*\/additional2$/);
|
||||
t.regex(config.queries["javascript"].custom[2].queries[0], /.*\/foo$/);
|
||||
t.regex(config.queries["javascript"].custom[0], /.*\/additional1$/);
|
||||
t.regex(config.queries["javascript"].custom[1], /.*\/additional2$/);
|
||||
t.regex(config.queries["javascript"].custom[2], /.*\/foo$/);
|
||||
});
|
||||
});
|
||||
ava_1.default("Invalid queries in workflow file handled correctly", async (t) => {
|
||||
@@ -442,7 +421,7 @@ ava_1.default("Invalid queries in workflow file handled correctly", async (t) =>
|
||||
// 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({
|
||||
async resolveQueries() {
|
||||
async resolveQueries(_queries, _extraSearchPath) {
|
||||
return {
|
||||
byLanguage: {
|
||||
javascript: {},
|
||||
@@ -453,7 +432,7 @@ ava_1.default("Invalid queries in workflow file handled correctly", async (t) =>
|
||||
},
|
||||
});
|
||||
try {
|
||||
await configUtils.initConfig(languages, queries, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
await configUtils.initConfig(languages, queries, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||
t.fail("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -496,7 +475,7 @@ ava_1.default("API client used when reading remote config", async (t) => {
|
||||
fs.mkdirSync(path.join(tmpDir, "foo/bar/dev"), { recursive: true });
|
||||
const configFile = "octo-org/codeql-config/config.yaml@main";
|
||||
const languages = "javascript";
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||
t.assert(spyGetContents.called);
|
||||
});
|
||||
});
|
||||
@@ -506,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, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -522,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, undefined, repoReference, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -533,13 +512,8 @@ ava_1.default("Invalid format of remote config handled correctly", async (t) =>
|
||||
ava_1.default("No detected languages", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
mockListLanguages([]);
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveLanguages() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
try {
|
||||
await configUtils.initConfig(undefined, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
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) {
|
||||
@@ -549,111 +523,16 @@ ava_1.default("No detected languages", async (t) => {
|
||||
});
|
||||
ava_1.default("Unknown languages", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const languages = "rubbish,english";
|
||||
const languages = "ruby,english";
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, undefined, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeql_1.getCachedCodeQL(), tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
await configUtils.initConfig(languages, undefined, undefined, { 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(["rubbish", "english"])));
|
||||
t.deepEqual(err, new Error(configUtils.getUnknownLanguagesError(["ruby", "english"])));
|
||||
}
|
||||
});
|
||||
});
|
||||
ava_1.default("Config specifies packages", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
const inputFileContents = `
|
||||
name: my config
|
||||
disable-default-queries: true
|
||||
packs:
|
||||
- a/b@1.2.3
|
||||
`;
|
||||
const configFile = path.join(tmpDir, "codeql-config.yaml");
|
||||
fs.writeFileSync(configFile, inputFileContents);
|
||||
const languages = "javascript";
|
||||
const { packs } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(packs, {
|
||||
[languages_1.Language.javascript]: [
|
||||
{
|
||||
packName: "a/b",
|
||||
version: semver_1.clean("1.2.3"),
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
ava_1.default("Config specifies packages for multiple languages", async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async resolveQueries() {
|
||||
return {
|
||||
byLanguage: {
|
||||
cpp: { "/foo/a.ql": {} },
|
||||
},
|
||||
noDeclaredLanguage: {},
|
||||
multipleDeclaredLanguages: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
const inputFileContents = `
|
||||
name: my config
|
||||
disable-default-queries: true
|
||||
queries:
|
||||
- uses: ./foo
|
||||
packs:
|
||||
javascript:
|
||||
- a/b@1.2.3
|
||||
python:
|
||||
- c/d@1.2.3
|
||||
`;
|
||||
const configFile = path.join(tmpDir, "codeql-config.yaml");
|
||||
fs.writeFileSync(configFile, inputFileContents);
|
||||
fs.mkdirSync(path.join(tmpDir, "foo"));
|
||||
const languages = "javascript,python,cpp";
|
||||
const { packs, queries } = await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example" }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(packs, {
|
||||
[languages_1.Language.javascript]: [
|
||||
{
|
||||
packName: "a/b",
|
||||
version: semver_1.clean("1.2.3"),
|
||||
},
|
||||
],
|
||||
[languages_1.Language.python]: [
|
||||
{
|
||||
packName: "c/d",
|
||||
version: semver_1.clean("1.2.3"),
|
||||
},
|
||||
],
|
||||
});
|
||||
t.deepEqual(queries, {
|
||||
cpp: {
|
||||
builtin: [],
|
||||
custom: [
|
||||
{
|
||||
queries: ["/foo/a.ql"],
|
||||
searchPath: tmpDir,
|
||||
},
|
||||
],
|
||||
},
|
||||
javascript: {
|
||||
builtin: [],
|
||||
custom: [],
|
||||
},
|
||||
python: {
|
||||
builtin: [],
|
||||
custom: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGenerator) {
|
||||
ava_1.default(`load invalid input - ${testName}`, async (t) => {
|
||||
return await util.withTmpDir(async (tmpDir) => {
|
||||
@@ -671,7 +550,7 @@ function doInvalidInputTest(testName, inputFileContents, expectedErrorMessageGen
|
||||
const inputFile = path.join(tmpDir, configFile);
|
||||
fs.writeFileSync(inputFile, inputFileContents, "utf8");
|
||||
try {
|
||||
await configUtils.initConfig(languages, undefined, undefined, configFile, undefined, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, gitHubVersion, sampleApiDetails, logging_1.getRunnerLogger(true));
|
||||
await configUtils.initConfig(languages, undefined, configFile, { owner: "github", repo: "example " }, tmpDir, tmpDir, codeQL, tmpDir, "token", "https://github.example.com", logging_1.getRunnerLogger(true));
|
||||
throw new Error("initConfig did not throw error");
|
||||
}
|
||||
catch (err) {
|
||||
@@ -725,11 +604,11 @@ ava_1.default("path validations", (t) => {
|
||||
// Dummy values to pass to validateAndSanitisePath
|
||||
const propertyName = "paths";
|
||||
const configFile = "./.github/codeql/config.yml";
|
||||
for (const validPath of validPaths) {
|
||||
t.truthy(configUtils.validateAndSanitisePath(validPath, propertyName, configFile, logging_1.getRunnerLogger(true)));
|
||||
for (const path of validPaths) {
|
||||
t.truthy(configUtils.validateAndSanitisePath(path, propertyName, configFile, logging_1.getRunnerLogger(true)));
|
||||
}
|
||||
for (const invalidPath of invalidPaths) {
|
||||
t.throws(() => configUtils.validateAndSanitisePath(invalidPath, propertyName, configFile, logging_1.getRunnerLogger(true)));
|
||||
for (const path of invalidPaths) {
|
||||
t.throws(() => configUtils.validateAndSanitisePath(path, propertyName, configFile, logging_1.getRunnerLogger(true)));
|
||||
}
|
||||
});
|
||||
ava_1.default("path sanitisation", (t) => {
|
||||
@@ -741,119 +620,4 @@ ava_1.default("path sanitisation", (t) => {
|
||||
// Trailing stars are stripped
|
||||
t.deepEqual(configUtils.validateAndSanitisePath("foo/**", propertyName, configFile, logging_1.getRunnerLogger(true)), "foo/");
|
||||
});
|
||||
/**
|
||||
* Test macro for ensuring the packs block is valid
|
||||
*/
|
||||
function parsePacksMacro(t, packsByLanguage, languages, expected) {
|
||||
t.deepEqual(configUtils.parsePacksFromConfig(packsByLanguage, languages, "/a/b"), expected);
|
||||
}
|
||||
parsePacksMacro.title = (providedTitle) => `Parse Packs: ${providedTitle}`;
|
||||
/**
|
||||
* Test macro for testing when the packs block is invalid
|
||||
*/
|
||||
function parsePacksErrorMacro(t, packsByLanguage, languages, expected) {
|
||||
t.throws(() => {
|
||||
configUtils.parsePacksFromConfig(packsByLanguage, languages, "/a/b");
|
||||
}, {
|
||||
message: expected,
|
||||
});
|
||||
}
|
||||
parsePacksErrorMacro.title = (providedTitle) => `Parse Packs Error: ${providedTitle}`;
|
||||
/**
|
||||
* Test macro for testing when the packs block is invalid
|
||||
*/
|
||||
function invalidPackNameMacro(t, name) {
|
||||
parsePacksErrorMacro(t, { [languages_1.Language.cpp]: [name] }, [languages_1.Language.cpp], new RegExp(`The configuration file "/a/b" is invalid: property "packs" "${name}" is not a valid pack`));
|
||||
}
|
||||
invalidPackNameMacro.title = (_, arg) => `Invalid pack string: ${arg}`;
|
||||
ava_1.default("no packs", parsePacksMacro, {}, [], {});
|
||||
ava_1.default("two packs", parsePacksMacro, ["a/b", "c/d@1.2.3"], [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: semver_1.clean("1.2.3") },
|
||||
],
|
||||
});
|
||||
ava_1.default("two packs with spaces", parsePacksMacro, [" a/b ", " c/d@1.2.3 "], [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: semver_1.clean("1.2.3") },
|
||||
],
|
||||
});
|
||||
ava_1.default("two packs with language", parsePacksMacro, {
|
||||
[languages_1.Language.cpp]: ["a/b", "c/d@1.2.3"],
|
||||
[languages_1.Language.java]: ["d/e", "f/g@1.2.3"],
|
||||
}, [languages_1.Language.cpp, languages_1.Language.java, languages_1.Language.csharp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: semver_1.clean("1.2.3") },
|
||||
],
|
||||
[languages_1.Language.java]: [
|
||||
{ packName: "d/e", version: undefined },
|
||||
{ packName: "f/g", version: semver_1.clean("1.2.3") },
|
||||
],
|
||||
});
|
||||
ava_1.default("no language", parsePacksErrorMacro, ["a/b@1.2.3"], [languages_1.Language.java, languages_1.Language.python], /The configuration file "\/a\/b" is invalid: property "packs" must split packages by language/);
|
||||
ava_1.default("invalid language", parsePacksErrorMacro, { [languages_1.Language.java]: ["c/d"] }, [languages_1.Language.cpp], /The configuration file "\/a\/b" is invalid: property "packs" has "java", but it is not one of the languages to analyze/);
|
||||
ava_1.default("not an array", parsePacksErrorMacro, { [languages_1.Language.cpp]: "c/d" }, [languages_1.Language.cpp], /The configuration file "\/a\/b" is invalid: property "packs" must be an array of non-empty strings/);
|
||||
ava_1.default(invalidPackNameMacro, "c"); // all packs require at least a scope and a name
|
||||
ava_1.default(invalidPackNameMacro, "c-/d");
|
||||
ava_1.default(invalidPackNameMacro, "-c/d");
|
||||
ava_1.default(invalidPackNameMacro, "c/d_d");
|
||||
ava_1.default(invalidPackNameMacro, "c/d@x");
|
||||
/**
|
||||
* Test macro for testing the packs block and the packs input
|
||||
*/
|
||||
function parseInputAndConfigMacro(t, packsFromConfig, packsFromInput, languages, expected) {
|
||||
t.deepEqual(configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b"), expected);
|
||||
}
|
||||
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
|
||||
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, expected) {
|
||||
t.throws(() => {
|
||||
configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b");
|
||||
}, {
|
||||
message: expected,
|
||||
});
|
||||
}
|
||||
parseInputAndConfigErrorMacro.title = (providedTitle) => `Parse Packs input and config Error: ${providedTitle}`;
|
||||
ava_1.default("input only", parseInputAndConfigMacro, {}, " c/d ", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [{ packName: "c/d", version: undefined }],
|
||||
});
|
||||
ava_1.default("input only with multiple", parseInputAndConfigMacro, {}, "a/b , c/d@1.2.3", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: "1.2.3" },
|
||||
],
|
||||
});
|
||||
ava_1.default("input only with +", parseInputAndConfigMacro, {}, " + a/b , c/d@1.2.3 ", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: "1.2.3" },
|
||||
],
|
||||
});
|
||||
ava_1.default("config only", parseInputAndConfigMacro, ["a/b", "c/d"], " ", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: undefined },
|
||||
],
|
||||
});
|
||||
ava_1.default("input overrides", parseInputAndConfigMacro, ["a/b", "c/d"], " e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "e/f", version: undefined },
|
||||
{ packName: "g/h", version: "1.2.3" },
|
||||
],
|
||||
});
|
||||
ava_1.default("input and config", parseInputAndConfigMacro, ["a/b", "c/d"], " +e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
|
||||
[languages_1.Language.cpp]: [
|
||||
{ packName: "e/f", version: undefined },
|
||||
{ packName: "g/h", version: "1.2.3" },
|
||||
{ packName: "a/b", version: undefined },
|
||||
{ packName: "c/d", version: undefined },
|
||||
],
|
||||
});
|
||||
ava_1.default("input with no language", parseInputAndConfigErrorMacro, {}, "c/d", [], /No languages specified/);
|
||||
ava_1.default("input with two languages", parseInputAndConfigErrorMacro, {}, "c/d", [languages_1.Language.cpp, languages_1.Language.csharp], /multi-language analysis/);
|
||||
ava_1.default("input with + only", parseInputAndConfigErrorMacro, {}, " + ", [languages_1.Language.cpp], /remove the '\+'/);
|
||||
ava_1.default("input with invalid pack name", parseInputAndConfigErrorMacro, {}, " xxx", [languages_1.Language.cpp], /"xxx" is not a valid pack/);
|
||||
// errors
|
||||
// input w invalid pack name
|
||||
//# sourceMappingURL=config-utils.test.js.map
|
||||
File diff suppressed because one or more lines are too long
91
lib/count-loc.js
generated
91
lib/count-loc.js
generated
@@ -1,91 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const github_linguist_1 = require("github-linguist");
|
||||
const languages_1 = require("./languages");
|
||||
const util_1 = require("./util");
|
||||
// Map from linguist language names to language prefixes used in the action and codeql
|
||||
const linguistToMetrics = {
|
||||
c: languages_1.Language.cpp,
|
||||
"c++": languages_1.Language.cpp,
|
||||
"c#": languages_1.Language.csharp,
|
||||
go: languages_1.Language.go,
|
||||
java: languages_1.Language.java,
|
||||
javascript: languages_1.Language.javascript,
|
||||
python: languages_1.Language.python,
|
||||
ruby: languages_1.Language.ruby,
|
||||
typescript: languages_1.Language.javascript,
|
||||
};
|
||||
const nameToLinguist = Object.entries(linguistToMetrics).reduce((obj, [key, name]) => {
|
||||
if (!obj[name]) {
|
||||
obj[name] = [];
|
||||
}
|
||||
obj[name].push(key);
|
||||
return obj;
|
||||
}, {});
|
||||
function getIdPrefix(language) {
|
||||
switch (language) {
|
||||
case languages_1.Language.cpp:
|
||||
return "cpp";
|
||||
case languages_1.Language.csharp:
|
||||
return "cs";
|
||||
case languages_1.Language.go:
|
||||
return "go";
|
||||
case languages_1.Language.java:
|
||||
return "java";
|
||||
case languages_1.Language.javascript:
|
||||
return "js";
|
||||
case languages_1.Language.python:
|
||||
return "py";
|
||||
case languages_1.Language.ruby:
|
||||
return "rb";
|
||||
default:
|
||||
util_1.assertNever(language);
|
||||
}
|
||||
}
|
||||
exports.getIdPrefix = getIdPrefix;
|
||||
/**
|
||||
* Count the lines of code of the specified language using the include
|
||||
* and exclude glob paths.
|
||||
*
|
||||
* @param cwd the root directory to start the count from
|
||||
* @param include glob patterns to include in the search for relevant files
|
||||
* @param exclude glob patterns to exclude in the search for relevant files
|
||||
* @param dbLanguages list of languages to include in the results
|
||||
* @param logger object to log results
|
||||
*/
|
||||
async function countLoc(cwd, include, exclude, dbLanguages, logger) {
|
||||
const result = await new github_linguist_1.LocDir({
|
||||
cwd,
|
||||
include: Array.isArray(include) && include.length > 0 ? include : ["**"],
|
||||
exclude,
|
||||
analysisLanguages: dbLanguages.flatMap((lang) => nameToLinguist[lang]),
|
||||
}).loadInfo();
|
||||
// The analysis counts LoC in all languages. We need to
|
||||
// extract the languages we care about. Also, note that
|
||||
// the analysis uses slightly different names for language.
|
||||
const lineCounts = Object.entries(result.languages).reduce((obj, [language, { code }]) => {
|
||||
const metricsLanguage = linguistToMetrics[language];
|
||||
if (metricsLanguage && dbLanguages.includes(metricsLanguage)) {
|
||||
obj[metricsLanguage] = code + (obj[metricsLanguage] || 0);
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
if (Object.keys(lineCounts).length) {
|
||||
logger.debug("Lines of code count:");
|
||||
for (const [language, count] of Object.entries(lineCounts)) {
|
||||
logger.debug(` ${language}: ${count}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.info("Could not determine the baseline lines of code count in this repository. " +
|
||||
"Because of this, it will not be possible to compare the lines " +
|
||||
"of code analyzed by code scanning with the baseline. This will not affect " +
|
||||
"the results produced by code scanning. If you have any questions, you can " +
|
||||
"raise an issue at https://github.com/github/codeql-action/issues. Please " +
|
||||
"include a link to the repository if public, or otherwise information about " +
|
||||
"the code scanning workflow you are using.");
|
||||
}
|
||||
return lineCounts;
|
||||
}
|
||||
exports.countLoc = countLoc;
|
||||
//# sourceMappingURL=count-loc.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"count-loc.js","sourceRoot":"","sources":["../src/count-loc.ts"],"names":[],"mappings":"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"}
|
||||
66
lib/count-loc.test.js
generated
66
lib/count-loc.test.js
generated
@@ -1,66 +0,0 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const count_loc_1 = require("./count-loc");
|
||||
const languages_1 = require("./languages");
|
||||
const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
ava_1.default("ensure lines of code works for cpp and js", async (t) => {
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.cpp, languages_1.Language.javascript], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
cpp: 6,
|
||||
javascript: 9,
|
||||
});
|
||||
});
|
||||
ava_1.default("ensure lines of code works for csharp", async (t) => {
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.csharp], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
csharp: 10,
|
||||
});
|
||||
});
|
||||
ava_1.default("ensure lines of code can handle undefined language", async (t) => {
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [languages_1.Language.javascript, languages_1.Language.python, "hucairz"], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
javascript: 9,
|
||||
python: 5,
|
||||
});
|
||||
});
|
||||
ava_1.default("ensure lines of code can handle empty languages", async (t) => {
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], [], [], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {});
|
||||
});
|
||||
ava_1.default("ensure lines of code can handle includes", async (t) => {
|
||||
// note that "**" is always included. The includes are for extra
|
||||
// directories outside the normal structure.
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), ["../../src/testdata"], [], [languages_1.Language.javascript], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
javascript: 12,
|
||||
});
|
||||
});
|
||||
ava_1.default("ensure lines of code can handle empty includes", async (t) => {
|
||||
// note that "**" is always included. The includes are for extra
|
||||
// directories outside the normal structure.
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), ["idontexist"], [], [languages_1.Language.javascript], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
// should get no results
|
||||
});
|
||||
});
|
||||
ava_1.default("ensure lines of code can handle exclude", async (t) => {
|
||||
const results = await count_loc_1.countLoc(path.join(__dirname, "../tests/multi-language-repo"), [], ["**/*.py"], [languages_1.Language.javascript, languages_1.Language.python], logging_1.getRunnerLogger(true));
|
||||
t.deepEqual(results, {
|
||||
javascript: 9,
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=count-loc.test.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"count-loc.test.js","sourceRoot":"","sources":["../src/count-loc.test.ts"],"names":[],"mappings":"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"}
|
||||
71
lib/database-upload.js
generated
71
lib/database-upload.js
generated
@@ -1,71 +0,0 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const api_client_1 = require("./api-client");
|
||||
const codeql_1 = require("./codeql");
|
||||
const util = __importStar(require("./util"));
|
||||
async function uploadDatabases(repositoryNwo, config, apiDetails, logger) {
|
||||
if (actionsUtil.getRequiredInput("upload-database") !== "true") {
|
||||
logger.debug("Database upload disabled in workflow. Skipping upload.");
|
||||
return;
|
||||
}
|
||||
// Do nothing when not running against github.com
|
||||
if (config.gitHubVersion.type !== util.GitHubVariant.DOTCOM) {
|
||||
logger.debug("Not running against github.com. Skipping upload.");
|
||||
return;
|
||||
}
|
||||
if (!(await actionsUtil.isAnalyzingDefaultBranch())) {
|
||||
// We only want to upload a database if we are analyzing the default branch.
|
||||
logger.debug("Not analyzing default branch. Skipping upload.");
|
||||
return;
|
||||
}
|
||||
const client = api_client_1.getApiClient(apiDetails);
|
||||
try {
|
||||
await client.request("GET /repos/:owner/:repo/code-scanning/databases", {
|
||||
owner: repositoryNwo.owner,
|
||||
repo: repositoryNwo.repo,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (util.isHTTPError(e) && e.status === 404) {
|
||||
logger.debug("Repository is not opted in to database uploads. Skipping upload.");
|
||||
}
|
||||
else {
|
||||
console.log(e);
|
||||
logger.info(`Skipping database upload due to unknown error: ${e}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const codeql = codeql_1.getCodeQL(config.codeQLCmd);
|
||||
for (const language of config.languages) {
|
||||
// Bundle the database up into a single zip file
|
||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||
const databaseBundlePath = `${databasePath}.zip`;
|
||||
await codeql.databaseBundle(databasePath, databaseBundlePath);
|
||||
// Upload the database bundle
|
||||
const payload = fs.readFileSync(databaseBundlePath);
|
||||
try {
|
||||
await client.request(`PUT /repos/:owner/:repo/code-scanning/databases/${language}`, {
|
||||
owner: repositoryNwo.owner,
|
||||
repo: repositoryNwo.repo,
|
||||
data: payload,
|
||||
});
|
||||
logger.debug(`Successfully uploaded database for ${language}`);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
// Log a warning but don't fail the workflow
|
||||
logger.warning(`Failed to upload database for ${language}: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.uploadDatabases = uploadDatabases;
|
||||
//# sourceMappingURL=database-upload.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"database-upload.js","sourceRoot":"","sources":["../src/database-upload.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AAEzB,4DAA8C;AAC9C,6CAA8D;AAC9D,qCAAqC;AAIrC,6CAA+B;AAExB,KAAK,UAAU,eAAe,CACnC,aAA4B,EAC5B,MAAc,EACd,UAA4B,EAC5B,MAAc;IAEd,IAAI,WAAW,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,KAAK,MAAM,EAAE;QAC9D,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACvE,OAAO;KACR;IAED,iDAAiD;IACjD,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;QAC3D,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACjE,OAAO;KACR;IAED,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,wBAAwB,EAAE,CAAC,EAAE;QACnD,4EAA4E;QAC5E,MAAM,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC/D,OAAO;KACR;IAED,MAAM,MAAM,GAAG,yBAAY,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI;QACF,MAAM,MAAM,CAAC,OAAO,CAAC,iDAAiD,EAAE;YACtE,KAAK,EAAE,aAAa,CAAC,KAAK;YAC1B,IAAI,EAAE,aAAa,CAAC,IAAI;SACzB,CAAC,CAAC;KACJ;IAAC,OAAO,CAAC,EAAE;QACV,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE;YAC3C,MAAM,CAAC,KAAK,CACV,kEAAkE,CACnE,CAAC;SACH;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,EAAE,CAAC,CAAC;SACpE;QACD,OAAO;KACR;IAED,MAAM,MAAM,GAAG,kBAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE;QACvC,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAClE,MAAM,kBAAkB,GAAG,GAAG,YAAY,MAAM,CAAC;QACjD,MAAM,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QAE9D,6BAA6B;QAC7B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;QACpD,IAAI;YACF,MAAM,MAAM,CAAC,OAAO,CAClB,mDAAmD,QAAQ,EAAE,EAC7D;gBACE,KAAK,EAAE,aAAa,CAAC,KAAK;gBAC1B,IAAI,EAAE,aAAa,CAAC,IAAI;gBACxB,IAAI,EAAE,OAAO;aACd,CACF,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;SAChE;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,4CAA4C;YAC5C,MAAM,CAAC,OAAO,CAAC,iCAAiC,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;SACnE;KACF;AACH,CAAC;AAlED,0CAkEC"}
|
||||
226
lib/database-upload.test.js
generated
226
lib/database-upload.test.js
generated
@@ -1,226 +0,0 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const github = __importStar(require("@actions/github"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const sinon_1 = __importDefault(require("sinon"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const apiClient = __importStar(require("./api-client"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const database_upload_1 = require("./database-upload");
|
||||
const languages_1 = require("./languages");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util_1 = require("./util");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
ava_1.default.beforeEach(() => {
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
|
||||
});
|
||||
const testRepoName = { owner: "github", repo: "example" };
|
||||
const testApiDetails = {
|
||||
auth: "1234",
|
||||
url: "https://github.com",
|
||||
};
|
||||
function getTestConfig(tmpDir) {
|
||||
return {
|
||||
languages: [languages_1.Language.javascript],
|
||||
queries: {},
|
||||
pathsIgnore: [],
|
||||
paths: [],
|
||||
originalUserInput: {},
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "foo",
|
||||
gitHubVersion: { type: util_1.GitHubVariant.DOTCOM },
|
||||
dbLocation: tmpDir,
|
||||
packs: {},
|
||||
};
|
||||
}
|
||||
function getRecordingLogger(messages) {
|
||||
return {
|
||||
debug: (message) => {
|
||||
messages.push({ type: "debug", message });
|
||||
console.debug(message);
|
||||
},
|
||||
info: (message) => {
|
||||
messages.push({ type: "info", message });
|
||||
console.info(message);
|
||||
},
|
||||
warning: (message) => {
|
||||
messages.push({ type: "warning", message });
|
||||
console.warn(message);
|
||||
},
|
||||
error: (message) => {
|
||||
messages.push({ type: "error", message });
|
||||
console.error(message);
|
||||
},
|
||||
isDebug: () => true,
|
||||
startGroup: () => undefined,
|
||||
endGroup: () => undefined,
|
||||
};
|
||||
}
|
||||
function mockHttpRequests(optInStatusCode, databaseUploadStatusCode) {
|
||||
// Passing an auth token is required, so we just use a dummy value
|
||||
const client = github.getOctokit("123");
|
||||
const requestSpy = sinon_1.default.stub(client, "request");
|
||||
const optInSpy = requestSpy.withArgs("GET /repos/:owner/:repo/code-scanning/databases");
|
||||
if (optInStatusCode < 300) {
|
||||
optInSpy.resolves(undefined);
|
||||
}
|
||||
else {
|
||||
optInSpy.throws(new util_1.HTTPError("some error message", optInStatusCode));
|
||||
}
|
||||
if (databaseUploadStatusCode !== undefined) {
|
||||
const databaseUploadSpy = requestSpy.withArgs("PUT /repos/:owner/:repo/code-scanning/databases/javascript");
|
||||
if (databaseUploadStatusCode < 300) {
|
||||
databaseUploadSpy.resolves(undefined);
|
||||
}
|
||||
else {
|
||||
databaseUploadSpy.throws(new util_1.HTTPError("some error message", databaseUploadStatusCode));
|
||||
}
|
||||
}
|
||||
sinon_1.default.stub(apiClient, "getApiClient").value(() => client);
|
||||
}
|
||||
ava_1.default("Abort database upload if 'upload-database' input set to false", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("false");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message === "Database upload disabled in workflow. Skipping upload.") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Abort database upload if running against GHES", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
const config = getTestConfig(tmpDir);
|
||||
config.gitHubVersion = { type: util_1.GitHubVariant.GHES, version: "3.0" };
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, config, testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message === "Not running against github.com. Skipping upload.") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Abort database upload if running against GHAE", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
const config = getTestConfig(tmpDir);
|
||||
config.gitHubVersion = { type: util_1.GitHubVariant.GHAE };
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, config, testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message === "Not running against github.com. Skipping upload.") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Abort database upload if not analyzing default branch", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(false);
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message === "Not analyzing default branch. Skipping upload.") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Abort database upload if opt-in request returns 404", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockHttpRequests(404);
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message ===
|
||||
"Repository is not opted in to database uploads. Skipping upload.") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Abort database upload if opt-in request fails with something other than 404", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockHttpRequests(500);
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "info" &&
|
||||
v.message ===
|
||||
"Skipping database upload due to unknown error: Error: some error message") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Don't crash if uploading a database fails", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockHttpRequests(204, 500);
|
||||
codeql_1.setCodeQL({
|
||||
async databaseBundle(_, outputFilePath) {
|
||||
fs.writeFileSync(outputFilePath, "");
|
||||
},
|
||||
});
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "warning" &&
|
||||
v.message ===
|
||||
"Failed to upload database for javascript: Error: some error message") !== undefined);
|
||||
});
|
||||
});
|
||||
ava_1.default("Successfully uploading a database", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
testing_utils_1.setupActionsVars(tmpDir, tmpDir);
|
||||
sinon_1.default
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon_1.default.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockHttpRequests(204, 201);
|
||||
codeql_1.setCodeQL({
|
||||
async databaseBundle(_, outputFilePath) {
|
||||
fs.writeFileSync(outputFilePath, "");
|
||||
},
|
||||
});
|
||||
const loggedMessages = [];
|
||||
await database_upload_1.uploadDatabases(testRepoName, getTestConfig(tmpDir), testApiDetails, getRecordingLogger(loggedMessages));
|
||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||
v.message === "Successfully uploaded database for javascript") !== undefined);
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=database-upload.test.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-20210702"
|
||||
"bundleVersion": "codeql-bundle-20200826"
|
||||
}
|
||||
|
||||
26
lib/external-queries.js
generated
26
lib/external-queries.js
generated
@@ -7,14 +7,13 @@ 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 toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
/**
|
||||
* Check out repository at the given ref, and return the directory of the checkout.
|
||||
*/
|
||||
async function checkoutExternalRepository(repository, ref, apiDetails, tempDir, logger) {
|
||||
async function checkoutExternalRepository(repository, ref, githubUrl, tempDir, logger) {
|
||||
logger.info(`Checking out ${repository}`);
|
||||
const checkoutLocation = path.join(tempDir, repository, ref);
|
||||
if (!checkoutLocation.startsWith(tempDir)) {
|
||||
@@ -22,13 +21,13 @@ async function checkoutExternalRepository(repository, ref, apiDetails, tempDir,
|
||||
throw new Error(`'${repository}@${ref}' is not a valid repository and reference.`);
|
||||
}
|
||||
if (!fs.existsSync(checkoutLocation)) {
|
||||
const repoCloneURL = buildCheckoutURL(repository, apiDetails);
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("git"), [
|
||||
const repoURL = `${githubUrl}/${repository}`;
|
||||
await new toolrunnner.ToolRunner("git", [
|
||||
"clone",
|
||||
repoCloneURL,
|
||||
repoURL,
|
||||
checkoutLocation,
|
||||
]).exec();
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("git"), [
|
||||
await new toolrunnner.ToolRunner("git", [
|
||||
`--work-tree=${checkoutLocation}`,
|
||||
`--git-dir=${checkoutLocation}/.git`,
|
||||
"checkout",
|
||||
@@ -38,17 +37,4 @@ async function checkoutExternalRepository(repository, ref, apiDetails, tempDir,
|
||||
return checkoutLocation;
|
||||
}
|
||||
exports.checkoutExternalRepository = checkoutExternalRepository;
|
||||
function buildCheckoutURL(repository, apiDetails) {
|
||||
const repoCloneURL = new URL(apiDetails.url);
|
||||
if (apiDetails.externalRepoAuth !== undefined) {
|
||||
repoCloneURL.username = "x-access-token";
|
||||
repoCloneURL.password = apiDetails.externalRepoAuth;
|
||||
}
|
||||
if (!repoCloneURL.pathname.endsWith("/")) {
|
||||
repoCloneURL.pathname += "/";
|
||||
}
|
||||
repoCloneURL.pathname += `${repository}`;
|
||||
return repoCloneURL.toString();
|
||||
}
|
||||
exports.buildCheckoutURL = buildCheckoutURL;
|
||||
//# sourceMappingURL=external-queries.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"external-queries.js","sourceRoot":"","sources":["../src/external-queries.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,yEAA2D;AAC3D,kEAAoD;AAKpD;;GAEG;AACI,KAAK,UAAU,0BAA0B,CAC9C,UAAkB,EAClB,GAAW,EACX,UAAwC,EACxC,OAAe,EACf,MAAc;IAEd,MAAM,CAAC,IAAI,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;IAE1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAE7D,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;QACzC,wGAAwG;QACxG,MAAM,IAAI,KAAK,CACb,IAAI,UAAU,IAAI,GAAG,4CAA4C,CAClE,CAAC;KACH;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QACpC,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChE,OAAO;YACP,YAAY;YACZ,gBAAgB;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChE,eAAe,gBAAgB,EAAE;YACjC,aAAa,gBAAgB,OAAO;YACpC,UAAU;YACV,GAAG;SACJ,CAAC,CAAC,IAAI,EAAE,CAAC;KACX;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAlCD,gEAkCC;AAED,SAAgB,gBAAgB,CAC9B,UAAkB,EAClB,UAAwC;IAExC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,gBAAgB,KAAK,SAAS,EAAE;QAC7C,YAAY,CAAC,QAAQ,GAAG,gBAAgB,CAAC;QACzC,YAAY,CAAC,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC;KACrD;IACD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACxC,YAAY,CAAC,QAAQ,IAAI,GAAG,CAAC;KAC9B;IACD,YAAY,CAAC,QAAQ,IAAI,GAAG,UAAU,EAAE,CAAC;IACzC,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC;AACjC,CAAC;AAdD,4CAcC"}
|
||||
{"version":3,"file":"external-queries.js","sourceRoot":"","sources":["../src/external-queries.ts"],"names":[],"mappings":";;;;;;;;;AAAA,0EAA4D;AAC5D,uCAAyB;AACzB,2CAA6B;AAI7B;;GAEG;AACI,KAAK,UAAU,0BAA0B,CAC9C,UAAkB,EAClB,GAAW,EACX,SAAiB,EACjB,OAAe,EACf,MAAc;IAEd,MAAM,CAAC,IAAI,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;IAE1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAE7D,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;QACzC,wGAAwG;QACxG,MAAM,IAAI,KAAK,CACb,IAAI,UAAU,IAAI,GAAG,4CAA4C,CAClE,CAAC;KACH;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QACpC,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;QAC7C,MAAM,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE;YACtC,OAAO;YACP,OAAO;YACP,gBAAgB;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE;YACtC,eAAe,gBAAgB,EAAE;YACjC,aAAa,gBAAgB,OAAO;YACpC,UAAU;YACV,GAAG;SACJ,CAAC,CAAC,IAAI,EAAE,CAAC;KACX;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAlCD,gEAkCC"}
|
||||
30
lib/external-queries.test.js
generated
30
lib/external-queries.test.js
generated
@@ -10,11 +10,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const externalQueries = __importStar(require("./external-queries"));
|
||||
const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
@@ -44,7 +43,7 @@ ava_1.default("checkoutExternalQueries", async (t) => {
|
||||
];
|
||||
console.log(`Running: git ${command.join(" ")}`);
|
||||
try {
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("git"), command, {
|
||||
await new toolrunnner.ToolRunner("git", command, {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
@@ -67,7 +66,6 @@ ava_1.default("checkoutExternalQueries", async (t) => {
|
||||
await runGit(["init", repoPath]);
|
||||
await runGit(["config", "user.email", "test@github.com"]);
|
||||
await runGit(["config", "user.name", "Test Test"]);
|
||||
await runGit(["config", "commit.gpgsign", "false"]);
|
||||
fs.writeFileSync(path.join(repoPath, "a"), "a content");
|
||||
await runGit(["add", "a"]);
|
||||
await runGit(["commit", "-m", "commit1"]);
|
||||
@@ -81,35 +79,17 @@ ava_1.default("checkoutExternalQueries", async (t) => {
|
||||
const commit2Sha = await runGit(["rev-parse", "HEAD"]);
|
||||
// Checkout the first commit, which should contain 'a' and 'b'
|
||||
t.false(fs.existsSync(path.join(tmpDir, repoName)));
|
||||
await externalQueries.checkoutExternalRepository(repoName, commit1Sha, { url: `file://${testRepoBaseDir}`, externalRepoAuth: "" }, tmpDir, logging_1.getRunnerLogger(true));
|
||||
await externalQueries.checkoutExternalRepository(repoName, commit1Sha, `file://${testRepoBaseDir}`, tmpDir, logging_1.getRunnerLogger(true));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName)));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName, commit1Sha)));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName, commit1Sha, "a")));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName, commit1Sha, "b")));
|
||||
// Checkout the second commit as well, which should only contain 'a'
|
||||
t.false(fs.existsSync(path.join(tmpDir, repoName, commit2Sha)));
|
||||
await externalQueries.checkoutExternalRepository(repoName, commit2Sha, { url: `file://${testRepoBaseDir}`, externalRepoAuth: "" }, tmpDir, logging_1.getRunnerLogger(true));
|
||||
await externalQueries.checkoutExternalRepository(repoName, commit2Sha, `file://${testRepoBaseDir}`, tmpDir, logging_1.getRunnerLogger(true));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName, commit2Sha)));
|
||||
t.true(fs.existsSync(path.join(tmpDir, repoName, commit2Sha, "a")));
|
||||
t.false(fs.existsSync(path.join(tmpDir, repoName, commit2Sha, "b")));
|
||||
});
|
||||
});
|
||||
ava_1.default("buildCheckoutURL", (t) => {
|
||||
t.deepEqual(externalQueries.buildCheckoutURL("foo/bar", {
|
||||
url: "https://github.com",
|
||||
externalRepoAuth: undefined,
|
||||
}), "https://github.com/foo/bar");
|
||||
t.deepEqual(externalQueries.buildCheckoutURL("foo/bar", {
|
||||
url: "https://github.example.com/",
|
||||
externalRepoAuth: undefined,
|
||||
}), "https://github.example.com/foo/bar");
|
||||
t.deepEqual(externalQueries.buildCheckoutURL("foo/bar", {
|
||||
url: "https://github.com",
|
||||
externalRepoAuth: "abc",
|
||||
}), "https://x-access-token:abc@github.com/foo/bar");
|
||||
t.deepEqual(externalQueries.buildCheckoutURL("foo/bar", {
|
||||
url: "https://github.example.com/",
|
||||
externalRepoAuth: "abc",
|
||||
}), "https://x-access-token:abc@github.example.com/foo/bar");
|
||||
});
|
||||
//# sourceMappingURL=external-queries.test.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"external-queries.test.js","sourceRoot":"","sources":["../src/external-queries.test.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"external-queries.test.js","sourceRoot":"","sources":["../src/external-queries.test.ts"],"names":[],"mappings":"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"}
|
||||
56
lib/fingerprints.js
generated
56
lib/fingerprints.js
generated
@@ -16,7 +16,6 @@ const tab = "\t".charCodeAt(0);
|
||||
const space = " ".charCodeAt(0);
|
||||
const lf = "\n".charCodeAt(0);
|
||||
const cr = "\r".charCodeAt(0);
|
||||
const EOF = 65535;
|
||||
const BLOCK_SIZE = 100;
|
||||
const MOD = long_1.default.fromInt(37); // L
|
||||
// Compute the starting point for the hash mod
|
||||
@@ -37,9 +36,9 @@ function computeFirstMod() {
|
||||
* the hashes of the lines near the end of the file.
|
||||
*
|
||||
* @param callback function that is called with the line number (1-based) and hash for every line
|
||||
* @param filepath The path to the file to hash
|
||||
* @param input The file's contents
|
||||
*/
|
||||
async function hash(callback, filepath) {
|
||||
function hash(callback, input) {
|
||||
// A rolling view in to the input
|
||||
const window = Array(BLOCK_SIZE).fill(0);
|
||||
// If the character in the window is the start of a new line
|
||||
@@ -47,7 +46,7 @@ async function hash(callback, filepath) {
|
||||
// Indexes match up with those from the window variable.
|
||||
const lineNumbers = Array(BLOCK_SIZE).fill(-1);
|
||||
// The current hash value, updated as we read each character
|
||||
let hashRaw = long_1.default.ZERO;
|
||||
let hash = long_1.default.ZERO;
|
||||
const firstMod = computeFirstMod();
|
||||
// The current index in the window, will wrap around to zero when we reach BLOCK_SIZE
|
||||
let index = 0;
|
||||
@@ -62,7 +61,7 @@ async function hash(callback, filepath) {
|
||||
const hashCounts = {};
|
||||
// Output the current hash and line number to the callback function
|
||||
const outputHash = function () {
|
||||
const hashValue = hashRaw.toUnsigned().toString(16);
|
||||
const hashValue = hash.toUnsigned().toString(16);
|
||||
if (!hashCounts[hashValue]) {
|
||||
hashCounts[hashValue] = 0;
|
||||
}
|
||||
@@ -74,7 +73,7 @@ async function hash(callback, filepath) {
|
||||
const updateHash = function (current) {
|
||||
const begin = window[index];
|
||||
window[index] = current;
|
||||
hashRaw = MOD.multiply(hashRaw)
|
||||
hash = MOD.multiply(hash)
|
||||
.add(long_1.default.fromInt(current))
|
||||
.subtract(firstMod.multiply(long_1.default.fromInt(begin)));
|
||||
index = (index + 1) % BLOCK_SIZE;
|
||||
@@ -83,11 +82,12 @@ async function hash(callback, filepath) {
|
||||
// as we go. Once we reach a point in the window again then we've processed
|
||||
// BLOCK_SIZE characters and if the last character at this point in the window
|
||||
// was the start of a line then we should output the hash for that line.
|
||||
const processCharacter = function (current) {
|
||||
for (let i = 0, len = input.length; i <= len; i++) {
|
||||
let current = i === len ? 65535 : input.charCodeAt(i);
|
||||
// skip tabs, spaces, and line feeds that come directly after a carriage return
|
||||
if (current === space || current === tab || (prevCR && current === lf)) {
|
||||
prevCR = false;
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
// replace CR with LF
|
||||
if (current === cr) {
|
||||
@@ -109,14 +109,7 @@ async function hash(callback, filepath) {
|
||||
lineStart = true;
|
||||
}
|
||||
updateHash(current);
|
||||
};
|
||||
const readStream = fs.createReadStream(filepath, "utf8");
|
||||
for await (const data of readStream) {
|
||||
for (let i = 0; i < data.length; ++i) {
|
||||
processCharacter(data.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
processCharacter(EOF);
|
||||
// Flush the remaining lines
|
||||
for (let i = 0; i < BLOCK_SIZE; i++) {
|
||||
if (lineNumbers[index] !== -1) {
|
||||
@@ -127,7 +120,7 @@ async function hash(callback, filepath) {
|
||||
}
|
||||
exports.hash = hash;
|
||||
// Generate a hash callback function that updates the given result in-place
|
||||
// when it receives a hash for the correct line number. Ignores hashes for other lines.
|
||||
// when it recieves a hash for the correct line number. Ignores hashes for other lines.
|
||||
function locationUpdateCallback(result, location, logger) {
|
||||
var _a, _b;
|
||||
let locationStartLine = (_b = (_a = location.physicalLocation) === null || _a === void 0 ? void 0 : _a.region) === null || _b === void 0 ? void 0 : _b.startLine;
|
||||
@@ -137,7 +130,7 @@ function locationUpdateCallback(result, location, logger) {
|
||||
// using the hash of the first line of the file.
|
||||
locationStartLine = 1;
|
||||
}
|
||||
return function (lineNumber, hashValue) {
|
||||
return function (lineNumber, hash) {
|
||||
// Ignore hashes for lines that don't concern us
|
||||
if (locationStartLine !== lineNumber) {
|
||||
return;
|
||||
@@ -149,10 +142,10 @@ function locationUpdateCallback(result, location, logger) {
|
||||
// If the hash doesn't match the existing fingerprint then
|
||||
// output a warning and don't overwrite it.
|
||||
if (!existingFingerprint) {
|
||||
result.partialFingerprints.primaryLocationLineHash = hashValue;
|
||||
result.partialFingerprints.primaryLocationLineHash = hash;
|
||||
}
|
||||
else if (existingFingerprint !== hashValue) {
|
||||
logger.warning(`Calculated fingerprint of ${hashValue} for file ${location.physicalLocation.artifactLocation.uri} line ${lineNumber}, but found existing inconsistent fingerprint value ${existingFingerprint}`);
|
||||
else if (existingFingerprint !== hash) {
|
||||
logger.warning(`Calculated fingerprint of ${hash} for file ${location.physicalLocation.artifactLocation.uri} line ${lineNumber}, but found existing inconsistent fingerprint value ${existingFingerprint}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -167,14 +160,14 @@ function resolveUriToFile(location, artifacts, checkoutPath, logger) {
|
||||
location.index < 0 ||
|
||||
location.index >= artifacts.length ||
|
||||
typeof artifacts[location.index].location !== "object") {
|
||||
logger.debug(`Ignoring location as index "${location.index}" is invalid`);
|
||||
logger.debug(`Ignoring location as URI "${location.index}" is invalid`);
|
||||
return undefined;
|
||||
}
|
||||
location = artifacts[location.index].location;
|
||||
}
|
||||
// Get the URI and decode
|
||||
if (typeof location.uri !== "string") {
|
||||
logger.debug(`Ignoring location as URI "${location.uri}" is invalid`);
|
||||
logger.debug(`Ignoring location as index "${location.uri}" is invalid`);
|
||||
return undefined;
|
||||
}
|
||||
let uri = decodeURIComponent(location.uri);
|
||||
@@ -204,17 +197,13 @@ function resolveUriToFile(location, artifacts, checkoutPath, logger) {
|
||||
logger.debug(`Unable to compute fingerprint for non-existent file: ${uri}`);
|
||||
return undefined;
|
||||
}
|
||||
if (fs.statSync(uri).isDirectory()) {
|
||||
logger.debug(`Unable to compute fingerprint for directory: ${uri}`);
|
||||
return undefined;
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
exports.resolveUriToFile = resolveUriToFile;
|
||||
// Compute fingerprints for results in the given sarif file
|
||||
// and return an updated sarif file contents.
|
||||
async function addFingerprints(sarifContents, checkoutPath, logger) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
function addFingerprints(sarifContents, checkoutPath, logger) {
|
||||
var _a, _b;
|
||||
const sarif = JSON.parse(sarifContents);
|
||||
// Gather together results for the same file and construct
|
||||
// callbacks to accept hashes for that file and update the location
|
||||
@@ -229,10 +218,6 @@ async function addFingerprints(sarifContents, checkoutPath, logger) {
|
||||
logger.debug(`Unable to compute fingerprint for invalid location: ${JSON.stringify(primaryLocation)}`);
|
||||
continue;
|
||||
}
|
||||
if (((_e = (_d = (_c = primaryLocation) === null || _c === void 0 ? void 0 : _c.physicalLocation) === null || _d === void 0 ? void 0 : _d.region) === null || _e === void 0 ? void 0 : _e.startLine) === undefined) {
|
||||
// Locations without a line number are unlikely to be source files
|
||||
continue;
|
||||
}
|
||||
const filepath = resolveUriToFile(primaryLocation.physicalLocation.artifactLocation, artifacts, checkoutPath, logger);
|
||||
if (!filepath) {
|
||||
continue;
|
||||
@@ -246,12 +231,13 @@ async function addFingerprints(sarifContents, checkoutPath, logger) {
|
||||
// Now hash each file that was found
|
||||
for (const [filepath, callbacks] of Object.entries(callbacksByFile)) {
|
||||
// A callback that forwards the hash to all other callbacks for that file
|
||||
const teeCallback = function (lineNumber, hashValue) {
|
||||
const teeCallback = function (lineNumber, hash) {
|
||||
for (const c of Object.values(callbacks)) {
|
||||
c(lineNumber, hashValue);
|
||||
c(lineNumber, hash);
|
||||
}
|
||||
};
|
||||
await hash(teeCallback, filepath);
|
||||
const fileContents = fs.readFileSync(filepath).toString();
|
||||
hash(teeCallback, fileContents);
|
||||
}
|
||||
return JSON.stringify(sarif);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
75
lib/fingerprints.test.js
generated
75
lib/fingerprints.test.js
generated
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
@@ -6,43 +9,35 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const fingerprints = __importStar(require("./fingerprints"));
|
||||
const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const util = __importStar(require("./util"));
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
async function testHash(t, input, expectedHashes) {
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
const tmpFile = path.resolve(tmpDir, "testfile");
|
||||
fs.writeFileSync(tmpFile, input);
|
||||
let index = 0;
|
||||
const callback = function (lineNumber, hash) {
|
||||
t.is(lineNumber, index + 1);
|
||||
t.is(hash, expectedHashes[index]);
|
||||
index++;
|
||||
};
|
||||
await fingerprints.hash(callback, tmpFile);
|
||||
t.is(index, input.split(/\r\n|\r|\n/).length);
|
||||
});
|
||||
function testHash(t, input, expectedHashes) {
|
||||
let index = 0;
|
||||
const callback = function (lineNumber, hash) {
|
||||
t.is(lineNumber, index + 1);
|
||||
t.is(hash, expectedHashes[index]);
|
||||
index++;
|
||||
};
|
||||
fingerprints.hash(callback, input);
|
||||
t.is(index, input.split(/\r\n|\r|\n/).length);
|
||||
}
|
||||
ava_1.default("hash", async (t) => {
|
||||
ava_1.default("hash", (t) => {
|
||||
// Try empty file
|
||||
await testHash(t, "", ["c129715d7a2bc9a3:1"]);
|
||||
testHash(t, "", ["c129715d7a2bc9a3:1"]);
|
||||
// Try various combinations of newline characters
|
||||
await testHash(t, " a\nb\n \t\tc\n d", [
|
||||
testHash(t, " a\nb\n \t\tc\n d", [
|
||||
"271789c17abda88f:1",
|
||||
"54703d4cd895b18:1",
|
||||
"180aee12dab6264:1",
|
||||
"a23a3dc5e078b07b:1",
|
||||
]);
|
||||
await testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End", [
|
||||
testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End", [
|
||||
"8b7cf3e952e7aeb2:1",
|
||||
"b1ae1287ec4718d9:1",
|
||||
"bff680108adb0fcc:1",
|
||||
@@ -50,7 +45,7 @@ ava_1.default("hash", async (t) => {
|
||||
"b86d3392aea1be30:1",
|
||||
"e6ceba753e1a442:1",
|
||||
]);
|
||||
await testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End\n", [
|
||||
testHash(t, " hello; \t\nworld!!!\n\n\n \t\tGreetings\n End\n", [
|
||||
"e9496ae3ebfced30:1",
|
||||
"fb7c023a8b9ccb3f:1",
|
||||
"ce8ba1a563dcdaca:1",
|
||||
@@ -59,7 +54,7 @@ ava_1.default("hash", async (t) => {
|
||||
"c8e28b0b4002a3a0:1",
|
||||
"c129715d7a2bc9a3:1",
|
||||
]);
|
||||
await testHash(t, " hello; \t\nworld!!!\r\r\r \t\tGreetings\r End\r", [
|
||||
testHash(t, " hello; \t\nworld!!!\r\r\r \t\tGreetings\r End\r", [
|
||||
"e9496ae3ebfced30:1",
|
||||
"fb7c023a8b9ccb3f:1",
|
||||
"ce8ba1a563dcdaca:1",
|
||||
@@ -68,7 +63,7 @@ ava_1.default("hash", async (t) => {
|
||||
"c8e28b0b4002a3a0:1",
|
||||
"c129715d7a2bc9a3:1",
|
||||
]);
|
||||
await testHash(t, " hello; \t\r\nworld!!!\r\n\r\n\r\n \t\tGreetings\r\n End\r\n", [
|
||||
testHash(t, " hello; \t\r\nworld!!!\r\n\r\n\r\n \t\tGreetings\r\n End\r\n", [
|
||||
"e9496ae3ebfced30:1",
|
||||
"fb7c023a8b9ccb3f:1",
|
||||
"ce8ba1a563dcdaca:1",
|
||||
@@ -77,7 +72,7 @@ ava_1.default("hash", async (t) => {
|
||||
"c8e28b0b4002a3a0:1",
|
||||
"c129715d7a2bc9a3:1",
|
||||
]);
|
||||
await testHash(t, " hello; \t\nworld!!!\r\n\n\r \t\tGreetings\r End\r\n", [
|
||||
testHash(t, " hello; \t\nworld!!!\r\n\n\r \t\tGreetings\r End\r\n", [
|
||||
"e9496ae3ebfced30:1",
|
||||
"fb7c023a8b9ccb3f:1",
|
||||
"ce8ba1a563dcdaca:1",
|
||||
@@ -87,7 +82,7 @@ ava_1.default("hash", async (t) => {
|
||||
"c129715d7a2bc9a3:1",
|
||||
]);
|
||||
// Try repeating line that will generate identical hashes
|
||||
await testHash(t, "Lorem ipsum dolor sit amet.\n".repeat(10), [
|
||||
testHash(t, "Lorem ipsum dolor sit amet.\n".repeat(10), [
|
||||
"a7f2ff13bc495cf2:1",
|
||||
"a7f2ff13bc495cf2:2",
|
||||
"a7f2ff13bc495cf2:3",
|
||||
@@ -100,7 +95,7 @@ ava_1.default("hash", async (t) => {
|
||||
"cc97dc7b1d7d8f7b:1",
|
||||
"c129715d7a2bc9a3:1",
|
||||
]);
|
||||
await testHash(t, "x = 2\nx = 1\nprint(x)\nx = 3\nprint(x)\nx = 4\nprint(x)\n", [
|
||||
testHash(t, "x = 2\nx = 1\nprint(x)\nx = 3\nprint(x)\nx = 4\nprint(x)\n", [
|
||||
"e54938cc54b302f1:1",
|
||||
"bb609acbe9138d60:1",
|
||||
"1131fd5871777f34:1",
|
||||
@@ -113,9 +108,7 @@ ava_1.default("hash", async (t) => {
|
||||
});
|
||||
function testResolveUriToFile(uri, index, artifactsURIs) {
|
||||
const location = { uri, index };
|
||||
const artifacts = artifactsURIs.map((artifactURI) => ({
|
||||
location: { uri: artifactURI },
|
||||
}));
|
||||
const artifacts = artifactsURIs.map((uri) => ({ location: { uri } }));
|
||||
return fingerprints.resolveUriToFile(location, artifacts, process.cwd(), logging_1.getRunnerLogger(true));
|
||||
}
|
||||
ava_1.default("resolveUriToFile", (t) => {
|
||||
@@ -126,13 +119,13 @@ ava_1.default("resolveUriToFile", (t) => {
|
||||
const cwd = process.cwd();
|
||||
const filepath = __filename;
|
||||
t.true(filepath.startsWith(`${cwd}/`));
|
||||
const relativeFilepath = filepath.substring(cwd.length + 1);
|
||||
const relativeFilepaht = filepath.substring(cwd.length + 1);
|
||||
// Absolute paths are unmodified
|
||||
t.is(testResolveUriToFile(filepath, undefined, []), filepath);
|
||||
t.is(testResolveUriToFile(`file://${filepath}`, undefined, []), filepath);
|
||||
// Relative paths are made absolute
|
||||
t.is(testResolveUriToFile(relativeFilepath, undefined, []), filepath);
|
||||
t.is(testResolveUriToFile(`file://${relativeFilepath}`, undefined, []), filepath);
|
||||
t.is(testResolveUriToFile(relativeFilepaht, undefined, []), filepath);
|
||||
t.is(testResolveUriToFile(`file://${relativeFilepaht}`, undefined, []), filepath);
|
||||
// Absolute paths outside the src root are discarded
|
||||
t.is(testResolveUriToFile("/src/foo/bar.js", undefined, []), undefined);
|
||||
t.is(testResolveUriToFile("file:///src/foo/bar.js", undefined, []), undefined);
|
||||
@@ -142,7 +135,7 @@ ava_1.default("resolveUriToFile", (t) => {
|
||||
// Invalid URIs are discarded
|
||||
t.is(testResolveUriToFile(1, undefined, []), undefined);
|
||||
t.is(testResolveUriToFile(undefined, undefined, []), undefined);
|
||||
// Non-existent files are discarded
|
||||
// Non-existant files are discarded
|
||||
t.is(testResolveUriToFile(`${filepath}2`, undefined, []), undefined);
|
||||
// Index is resolved
|
||||
t.is(testResolveUriToFile(undefined, 0, [filepath]), filepath);
|
||||
@@ -150,12 +143,8 @@ ava_1.default("resolveUriToFile", (t) => {
|
||||
// Invalid indexes are discarded
|
||||
t.is(testResolveUriToFile(undefined, 1, [filepath]), undefined);
|
||||
t.is(testResolveUriToFile(undefined, "0", [filepath]), undefined);
|
||||
// Directories are discarded
|
||||
const dirpath = __dirname;
|
||||
t.is(testResolveUriToFile(dirpath, undefined, []), undefined);
|
||||
t.is(testResolveUriToFile(`file://${dirpath}`, undefined, []), undefined);
|
||||
});
|
||||
ava_1.default("addFingerprints", async (t) => {
|
||||
ava_1.default("addFingerprints", (t) => {
|
||||
// Run an end-to-end test on a test file
|
||||
let input = fs
|
||||
.readFileSync(`${__dirname}/../src/testdata/fingerprinting.input.sarif`)
|
||||
@@ -168,9 +157,9 @@ ava_1.default("addFingerprints", async (t) => {
|
||||
expected = JSON.stringify(JSON.parse(expected));
|
||||
// The URIs in the SARIF files resolve to files in the testdata directory
|
||||
const checkoutPath = path.normalize(`${__dirname}/../src/testdata`);
|
||||
t.deepEqual(await fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
|
||||
t.deepEqual(fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
|
||||
});
|
||||
ava_1.default("missingRegions", async (t) => {
|
||||
ava_1.default("missingRegions", (t) => {
|
||||
// Run an end-to-end test on a test file
|
||||
let input = fs
|
||||
.readFileSync(`${__dirname}/../src/testdata/fingerprinting2.input.sarif`)
|
||||
@@ -183,6 +172,6 @@ ava_1.default("missingRegions", async (t) => {
|
||||
expected = JSON.stringify(JSON.parse(expected));
|
||||
// The URIs in the SARIF files resolve to files in the testdata directory
|
||||
const checkoutPath = path.normalize(`${__dirname}/../src/testdata`);
|
||||
t.deepEqual(await fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
|
||||
t.deepEqual(fingerprints.addFingerprints(input, checkoutPath, logging_1.getRunnerLogger(true)), expected);
|
||||
});
|
||||
//# sourceMappingURL=fingerprints.test.js.map
|
||||
File diff suppressed because one or more lines are too long
71
lib/init-action.js
generated
71
lib/init-action.js
generated
@@ -8,26 +8,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const actions_util_1 = require("./actions-util");
|
||||
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");
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
async function sendSuccessStatusReport(startedAt, config, toolsVersion) {
|
||||
async function sendSuccessStatusReport(startedAt, config) {
|
||||
var _a;
|
||||
const statusReportBase = await actions_util_1.createStatusReportBase("init", "success", startedAt);
|
||||
const statusReportBase = await actionsUtil.createStatusReportBase("init", "success", startedAt);
|
||||
const languages = config.languages.join(",");
|
||||
const workflowLanguages = actions_util_1.getOptionalInput("languages");
|
||||
const workflowLanguages = actionsUtil.getOptionalInput("languages");
|
||||
const paths = (config.originalUserInput.paths || []).join(",");
|
||||
const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join(",");
|
||||
const disableDefaultQueries = config.originalUserInput["disable-default-queries"]
|
||||
? languages
|
||||
: "";
|
||||
const queries = [];
|
||||
let queriesInput = (_a = actions_util_1.getOptionalInput("queries")) === null || _a === void 0 ? void 0 : _a.trim();
|
||||
let queriesInput = (_a = actionsUtil.getOptionalInput("queries")) === null || _a === void 0 ? void 0 : _a.trim();
|
||||
if (queriesInput === undefined || queriesInput.startsWith("+")) {
|
||||
queries.push(...(config.originalUserInput.queries || []).map((q) => q.uses));
|
||||
}
|
||||
@@ -45,48 +41,32 @@ async function sendSuccessStatusReport(startedAt, config, toolsVersion) {
|
||||
paths_ignore: pathsIgnore,
|
||||
disable_default_queries: disableDefaultQueries,
|
||||
queries: queries.join(","),
|
||||
tools_input: actions_util_1.getOptionalInput("tools") || "",
|
||||
tools_resolved_version: toolsVersion,
|
||||
};
|
||||
await actions_util_1.sendStatusReport(statusReport);
|
||||
await actionsUtil.sendStatusReport(statusReport);
|
||||
}
|
||||
async function run() {
|
||||
const startedAt = new Date();
|
||||
const logger = logging_1.getActionsLogger();
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
|
||||
let config;
|
||||
let codeql;
|
||||
let toolsVersion;
|
||||
const apiDetails = {
|
||||
auth: actions_util_1.getRequiredInput("token"),
|
||||
externalRepoAuth: actions_util_1.getOptionalInput("external-repository-token"),
|
||||
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
|
||||
util_1.checkGitHubVersionInRange(gitHubVersion, logger, util_1.Mode.actions);
|
||||
try {
|
||||
const workflowErrors = await actions_util_1.validateWorkflow();
|
||||
if (!(await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "starting", startedAt, workflowErrors)))) {
|
||||
actionsUtil.prepareLocalRunEnvironment();
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "starting", startedAt), true))) {
|
||||
return;
|
||||
}
|
||||
const initCodeQLResult = await init_1.initCodeQL(actions_util_1.getOptionalInput("tools"), apiDetails, actions_util_1.getTemporaryDirectory(), actions_util_1.getToolCacheDirectory(), gitHubVersion.type, logger);
|
||||
codeql = initCodeQLResult.codeql;
|
||||
toolsVersion = initCodeQLResult.toolsVersion;
|
||||
config = await init_1.initConfig(actions_util_1.getOptionalInput("languages"), actions_util_1.getOptionalInput("queries"), actions_util_1.getOptionalInput("packs"), actions_util_1.getOptionalInput("config-file"), actions_util_1.getOptionalInput("db-location"), repository_1.parseRepositoryNwo(util_1.getRequiredEnvParam("GITHUB_REPOSITORY")), actions_util_1.getTemporaryDirectory(), util_1.getRequiredEnvParam("RUNNER_TOOL_CACHE"), codeql, util_1.getRequiredEnvParam("GITHUB_WORKSPACE"), gitHubVersion, apiDetails, logger);
|
||||
if (config.languages.includes(languages_1.Language.python) &&
|
||||
actions_util_1.getRequiredInput("setup-python-dependencies") === "true") {
|
||||
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`);
|
||||
}
|
||||
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`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
core.setFailed(e.message);
|
||||
console.log(e);
|
||||
await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "aborted", startedAt, e.message));
|
||||
await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "aborted", startedAt, e.message));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -108,24 +88,17 @@ async function run() {
|
||||
await init_1.injectWindowsTracer("Runner.Worker.exe", undefined, config, codeql, tracerConfig);
|
||||
}
|
||||
}
|
||||
core.setOutput("codeql-path", config.codeQLCmd);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
console.log(error);
|
||||
await actions_util_1.sendStatusReport(await actions_util_1.createStatusReportBase("init", "failure", startedAt, error.message, error.stack));
|
||||
await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("init", "failure", startedAt, error.message, error.stack));
|
||||
return;
|
||||
}
|
||||
await sendSuccessStatusReport(startedAt, config, toolsVersion);
|
||||
await sendSuccessStatusReport(startedAt, config);
|
||||
}
|
||||
async function runWrapper() {
|
||||
try {
|
||||
await run();
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`init action failed: ${error}`);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
void runWrapper();
|
||||
run().catch((e) => {
|
||||
core.setFailed(`init action failed: ${e}`);
|
||||
console.log(e);
|
||||
});
|
||||
//# sourceMappingURL=init-action.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,iDASwB;AAGxB,iCAMgB;AAChB,2CAAuC;AACvC,uCAA6C;AAC7C,6CAAkD;AAClD,iCAMgB;AAEhB,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAsBvC,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,MAA0B,EAC1B,YAAoB;;IAEpB,MAAM,gBAAgB,GAAG,MAAM,qCAAsB,CACnD,MAAM,EACN,SAAS,EACT,SAAS,CACV,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,+BAAgB,CAAC,WAAW,CAAC,CAAC;IACxD,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,+BAAgB,CAAC,SAAS,CAAC,0CAAE,IAAI,EAAE,CAAC;IACvD,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;QAC1B,WAAW,EAAE,+BAAgB,CAAC,OAAO,CAAC,IAAI,EAAE;QAC5C,sBAAsB,EAAE,YAAY;KACrC,CAAC;IAEF,MAAM,+BAAgB,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,0BAAgB,EAAE,CAAC;IAClC,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,MAA0B,CAAC;IAC/B,IAAI,MAAc,CAAC;IACnB,IAAI,YAAoB,CAAC;IAEzB,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,+BAAgB,CAAC,OAAO,CAAC;QAC/B,gBAAgB,EAAE,+BAAgB,CAAC,2BAA2B,CAAC;QAC/D,GAAG,EAAE,0BAAmB,CAAC,mBAAmB,CAAC;KAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,uBAAgB,CAAC,UAAU,CAAC,CAAC;IACzD,gCAAyB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAI,CAAC,OAAO,CAAC,CAAC;IAE/D,IAAI;QACF,MAAM,cAAc,GAAG,MAAM,+BAAgB,EAAE,CAAC;QAEhD,IACE,CAAC,CAAC,MAAM,+BAAgB,CACtB,MAAM,qCAAsB,CAC1B,MAAM,EACN,UAAU,EACV,SAAS,EACT,cAAc,CACf,CACF,CAAC,EACF;YACA,OAAO;SACR;QAED,MAAM,gBAAgB,GAAG,MAAM,iBAAU,CACvC,+BAAgB,CAAC,OAAO,CAAC,EACzB,UAAU,EACV,oCAAqB,EAAE,EACvB,oCAAqB,EAAE,EACvB,aAAa,CAAC,IAAI,EAClB,MAAM,CACP,CAAC;QACF,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;QACjC,YAAY,GAAG,gBAAgB,CAAC,YAAY,CAAC;QAE7C,MAAM,GAAG,MAAM,iBAAU,CACvB,+BAAgB,CAAC,WAAW,CAAC,EAC7B,+BAAgB,CAAC,SAAS,CAAC,EAC3B,+BAAgB,CAAC,OAAO,CAAC,EACzB,+BAAgB,CAAC,aAAa,CAAC,EAC/B,+BAAgB,CAAC,aAAa,CAAC,EAC/B,+BAAkB,CAAC,0BAAmB,CAAC,mBAAmB,CAAC,CAAC,EAC5D,oCAAqB,EAAE,EACvB,0BAAmB,CAAC,mBAAmB,CAAC,EACxC,MAAM,EACN,0BAAmB,CAAC,kBAAkB,CAAC,EACvC,aAAa,EACb,UAAU,EACV,MAAM,CACP,CAAC;QAEF,IACE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,oBAAQ,CAAC,MAAM,CAAC;YAC1C,+BAAgB,CAAC,2BAA2B,CAAC,KAAK,MAAM,EACxD;YACA,IAAI;gBACF,MAAM,wBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;aACzC;YAAC,OAAO,GAAG,EAAE;gBACZ,MAAM,CAAC,OAAO,CACZ,GAAG,GAAG,CAAC,OAAO,2FAA2F,CAC1G,CAAC;aACH;SACF;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,+BAAgB,CACpB,MAAM,qCAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,CACtE,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;QAED,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;KACjD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,+BAAgB,CACpB,MAAM,qCAAsB,CAC1B,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,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
|
||||
{"version":3,"file":"init-action.js","sourceRoot":"","sources":["../src/init-action.ts"],"names":[],"mappings":"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"}
|
||||
55
lib/init.js
generated
55
lib/init.js
generated
@@ -7,26 +7,25 @@ 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 toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
const analysisPaths = __importStar(require("./analysis-paths"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const configUtils = __importStar(require("./config-utils"));
|
||||
const tracer_config_1 = require("./tracer-config");
|
||||
const util = __importStar(require("./util"));
|
||||
async function initCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger) {
|
||||
async function initCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger) {
|
||||
logger.startGroup("Setup CodeQL tools");
|
||||
const { codeql, toolsVersion } = await codeql_1.setupCodeQL(codeqlURL, apiDetails, tempDir, toolCacheDir, variant, logger);
|
||||
const codeql = await codeql_1.setupCodeQL(codeqlURL, githubAuth, githubUrl, tempDir, toolsDir, mode, logger);
|
||||
await codeql.printVersion();
|
||||
logger.endGroup();
|
||||
return { codeql, toolsVersion };
|
||||
return codeql;
|
||||
}
|
||||
exports.initCodeQL = initCodeQL;
|
||||
async function initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger) {
|
||||
async function initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger) {
|
||||
logger.startGroup("Load language configuration");
|
||||
const config = await configUtils.initConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, repository, tempDir, toolCacheDir, codeQL, checkoutPath, gitHubVersion, apiDetails, logger);
|
||||
const config = await configUtils.initConfig(languagesInput, queriesInput, configFile, repository, tempDir, toolCacheDir, codeQL, checkoutPath, githubAuth, githubUrl, logger);
|
||||
analysisPaths.printPathFiltersWarning(config, logger);
|
||||
logger.endGroup();
|
||||
return config;
|
||||
@@ -34,11 +33,11 @@ async function initConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||
exports.initConfig = initConfig;
|
||||
async function runInit(codeql, config) {
|
||||
const sourceRoot = path.resolve();
|
||||
fs.mkdirSync(config.dbLocation, { recursive: true });
|
||||
fs.mkdirSync(util.getCodeQLDatabasesDir(config.tempDir), { recursive: true });
|
||||
// TODO: replace this code once CodeQL supports multi-language tracing
|
||||
for (const language of config.languages) {
|
||||
// Init language database
|
||||
await codeql.databaseInit(util.getCodeQLDatabasePath(config, language), language, sourceRoot);
|
||||
await codeql.databaseInit(util.getCodeQLDatabasePath(config.tempDir, language), language, sourceRoot);
|
||||
}
|
||||
return await tracer_config_1.getCombinedTracerConfig(config, codeql);
|
||||
}
|
||||
@@ -103,10 +102,6 @@ async function injectWindowsTracer(processName, processLevel, config, codeql, tr
|
||||
Write-Host "Found Runner.Worker.exe process which means we are running on GitHub Actions"
|
||||
Write-Host "Aborting search early and using process: $p"
|
||||
Break
|
||||
} elseif ($p[0].Name -eq "Agent.Worker.exe") {
|
||||
Write-Host "Found Agent.Worker.exe process which means we are running on Azure Pipelines"
|
||||
Write-Host "Aborting search early and using process: $p"
|
||||
Break
|
||||
} else {
|
||||
$id = $p[0].ParentProcessId
|
||||
}
|
||||
@@ -117,7 +112,7 @@ async function injectWindowsTracer(processName, processLevel, config, codeql, tr
|
||||
}
|
||||
const injectTracerPath = path.join(config.tempDir, "inject-tracer.ps1");
|
||||
fs.writeFileSync(injectTracerPath, script);
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("powershell"), [
|
||||
await new toolrunnner.ToolRunner("powershell", [
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-file",
|
||||
@@ -128,45 +123,31 @@ async function injectWindowsTracer(processName, processLevel, config, codeql, tr
|
||||
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
|
||||
// Setup tools on the Github hosted runners
|
||||
if (process.env["ImageOS"] !== undefined) {
|
||||
try {
|
||||
if (process.platform === "win32") {
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("powershell"), [path.join(scriptsFolder, "install_tools.ps1")]).exec();
|
||||
}
|
||||
else {
|
||||
await new toolrunner.ToolRunner(path.join(scriptsFolder, "install_tools.sh")).exec();
|
||||
}
|
||||
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 dependencies. You can call this action with 'setup-python-dependencies: false' to disable this process.");
|
||||
return;
|
||||
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 {
|
||||
const script = "auto_install_packages.py";
|
||||
if (process.platform === "win32") {
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("py"), [
|
||||
"-3",
|
||||
path.join(scriptsFolder, script),
|
||||
path.dirname(codeql.getPath()),
|
||||
]).exec();
|
||||
}
|
||||
else {
|
||||
await new toolrunner.ToolRunner(path.join(scriptsFolder, script), [
|
||||
path.dirname(codeql.getPath()),
|
||||
]).exec();
|
||||
}
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
|
||||
@@ -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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"}
|
||||
5
lib/languages.js
generated
5
lib/languages.js
generated
@@ -9,7 +9,6 @@ var Language;
|
||||
Language["java"] = "java";
|
||||
Language["javascript"] = "javascript";
|
||||
Language["python"] = "python";
|
||||
Language["ruby"] = "ruby";
|
||||
})(Language = exports.Language || (exports.Language = {}));
|
||||
// Additional names for languages
|
||||
const LANGUAGE_ALIASES = {
|
||||
@@ -34,9 +33,7 @@ function parseLanguage(language) {
|
||||
}
|
||||
exports.parseLanguage = parseLanguage;
|
||||
function isTracedLanguage(language) {
|
||||
return (["cpp", "java", "csharp"].includes(language) ||
|
||||
(process.env["CODEQL_EXTRACTOR_GO_BUILD_TRACING"] === "on" &&
|
||||
language === Language.go));
|
||||
return ["cpp", "java", "csharp"].includes(language);
|
||||
}
|
||||
exports.isTracedLanguage = isTracedLanguage;
|
||||
function isScannedLanguage(language) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;AAAA,wCAAwC;AACxC,IAAY,QAQX;AARD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;AACf,CAAC,EARW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAQnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CACL,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,KAAK,IAAI;YACxD,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC,CAC5B,CAAC;AACJ,CAAC;AAND,4CAMC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
||||
{"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"}
|
||||
2
lib/languages.test.js
generated
2
lib/languages.test.js
generated
@@ -7,7 +7,7 @@ const ava_1 = __importDefault(require("ava"));
|
||||
const languages_1 = require("./languages");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
ava_1.default("parseLanguage", async (t) => {
|
||||
ava_1.default("parseLangauge", async (t) => {
|
||||
// Exact matches
|
||||
t.deepEqual(languages_1.parseLanguage("csharp"), languages_1.Language.csharp);
|
||||
t.deepEqual(languages_1.parseLanguage("cpp"), languages_1.Language.cpp);
|
||||
|
||||
1
lib/logging.js
generated
1
lib/logging.js
generated
@@ -18,7 +18,6 @@ function getRunnerLogger(debugMode) {
|
||||
info: console.info,
|
||||
warning: console.warn,
|
||||
error: console.error,
|
||||
isDebug: () => debugMode,
|
||||
startGroup: () => undefined,
|
||||
endGroup: () => undefined,
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AActC,SAAgB,gBAAgB;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAFD,4CAEC;AAED,SAAgB,eAAe,CAAC,SAAkB;IAChD,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS;QAClD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;QACxB,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;KAC1B,CAAC;AACJ,CAAC;AAVD,0CAUC"}
|
||||
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAYtC,SAAgB,gBAAgB;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAFD,4CAEC;AAED,SAAgB,eAAe,CAAC,SAAkB;IAChD,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,SAAS;QAClD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS;KAC1B,CAAC;AACJ,CAAC;AATD,0CASC"}
|
||||
93
lib/runner.js
generated
93
lib/runner.js
generated
@@ -7,10 +7,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commander_1 = require("commander");
|
||||
const fs = __importStar(require("fs"));
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const commander_1 = require("commander");
|
||||
const analyze_1 = require("./analyze");
|
||||
const autobuild_1 = require("./autobuild");
|
||||
const codeql_1 = require("./codeql");
|
||||
@@ -21,12 +21,26 @@ const logging_1 = require("./logging");
|
||||
const repository_1 = require("./repository");
|
||||
const upload_lib = __importStar(require("./upload-lib"));
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
const program = new commander_1.Command();
|
||||
program.version(pkg.version).hook("preAction", () => {
|
||||
util_1.initializeEnvironment(util_1.Mode.runner, pkg.version);
|
||||
});
|
||||
program.version("0.0.1");
|
||||
function parseGithubUrl(inputUrl) {
|
||||
try {
|
||||
const url = new URL(inputUrl);
|
||||
// If we detect this is trying to be to github.com
|
||||
// then return with a fixed canonical URL.
|
||||
if (url.hostname === "github.com" || url.hostname === "api.github.com") {
|
||||
return "https://github.com";
|
||||
}
|
||||
// Remove the API prefix if it's present
|
||||
if (url.pathname.indexOf("/api/v3") !== -1) {
|
||||
url.pathname = url.pathname.substring(0, url.pathname.indexOf("/api/v3"));
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`"${inputUrl}" is not a valid URL`);
|
||||
}
|
||||
}
|
||||
function getTempDir(userInput) {
|
||||
const tempDir = path.join(userInput || process.cwd(), "codeql-runner");
|
||||
if (!fs.existsSync(tempDir)) {
|
||||
@@ -86,24 +100,18 @@ program
|
||||
.description("Initializes CodeQL")
|
||||
.requiredOption("--repository <repository>", "Repository name. (Required)")
|
||||
.requiredOption("--github-url <url>", "URL of GitHub instance. (Required)")
|
||||
.option("--github-auth <auth>", "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead.")
|
||||
.option("--github-auth-stdin", "Read GitHub Apps token or personal access token from stdin.")
|
||||
.requiredOption("--github-auth <auth>", "GitHub Apps token or personal access token. (Required)")
|
||||
.option("--languages <languages>", "Comma-separated list of languages to analyze. Otherwise detects and analyzes all supported languages from the repo.")
|
||||
.option("--queries <queries>", "Comma-separated list of additional queries to run. This overrides the same setting in a configuration file.")
|
||||
.option("--packs <packs>", `[Experimental] Comma-separated list of packs to run. Reference a pack in the format scope/name[@version]. If version is not
|
||||
specified, then the latest version of the pack is used. By default, this overrides the same setting in a
|
||||
configuration file; prefix with "+" to use both sets of packs.
|
||||
|
||||
This option is only available in single-language analyses. To use packs in multi-language
|
||||
analyses, you must specify packs in the codeql-config.yml file.`)
|
||||
.option("--config-file <file>", "Path to config file.")
|
||||
.option("--codeql-path <path>", "Path to a copy of the CodeQL CLI executable to use. Otherwise downloads a copy.")
|
||||
.option("--temp-dir <dir>", 'Directory to use for temporary files. Default is "./codeql-runner".')
|
||||
.option("--tools-dir <dir>", "Directory to use for CodeQL tools and other files to store between runs. Default is a subdirectory of the home directory.")
|
||||
.option("--checkout-path <path>", "Checkout path. Default is the current working directory.")
|
||||
.option("--debug", "Print more verbose output", false)
|
||||
.option("--trace-process-name <string>", "(Advanced, windows-only) Inject a windows tracer of this process into a process with the given process name.")
|
||||
.option("--trace-process-level <number>", "(Advanced, windows-only) Inject a windows tracer of this process into a parent process <number> levels up.")
|
||||
// This prevents a message like: error: unknown option '--trace-process-level'
|
||||
// Remove this if commander.js starts supporting hidden options.
|
||||
.allowUnknownOption()
|
||||
.action(async (cmd) => {
|
||||
const logger = logging_1.getRunnerLogger(cmd.debug);
|
||||
try {
|
||||
@@ -113,22 +121,14 @@ program
|
||||
logger.info(`Cleaning temp directory ${tempDir}`);
|
||||
fs.rmdirSync(tempDir, { recursive: true });
|
||||
fs.mkdirSync(tempDir, { recursive: true });
|
||||
const auth = await util_1.getGitHubAuth(logger, cmd.githubAuth, cmd.githubAuthStdin);
|
||||
const apiDetails = {
|
||||
auth,
|
||||
externalRepoAuth: auth,
|
||||
url: util_1.parseGitHubUrl(cmd.githubUrl),
|
||||
};
|
||||
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
|
||||
util_1.checkGitHubVersionInRange(gitHubVersion, logger, util_1.Mode.runner);
|
||||
let codeql;
|
||||
if (cmd.codeqlPath !== undefined) {
|
||||
codeql = codeql_1.getCodeQL(cmd.codeqlPath);
|
||||
}
|
||||
else {
|
||||
codeql = (await init_1.initCodeQL(undefined, apiDetails, tempDir, toolsDir, gitHubVersion.type, logger)).codeql;
|
||||
codeql = await init_1.initCodeQL(undefined, cmd.githubAuth, parseGithubUrl(cmd.githubUrl), tempDir, toolsDir, "runner", logger);
|
||||
}
|
||||
const config = await init_1.initConfig(cmd.languages, cmd.queries, cmd.packs, cmd.configFile, undefined, repository_1.parseRepositoryNwo(cmd.repository), tempDir, toolsDir, codeql, cmd.checkoutPath || process.cwd(), gitHubVersion, apiDetails, logger);
|
||||
const 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 tracerConfig = await init_1.runInit(codeql, config);
|
||||
if (tracerConfig === undefined) {
|
||||
return;
|
||||
@@ -136,7 +136,7 @@ program
|
||||
if (process.platform === "win32") {
|
||||
await init_1.injectWindowsTracer(parseTraceProcessName(), parseTraceProcessLevel(), config, codeql, tracerConfig);
|
||||
}
|
||||
// Always output a json file of the env that can be consumed programmatically
|
||||
// Always output a json file of the env that can be consumed programatically
|
||||
const jsonEnvFile = path.join(config.tempDir, codeqlEnvJsonFilename);
|
||||
fs.writeFileSync(jsonEnvFile, JSON.stringify(tracerConfig.env));
|
||||
if (process.platform === "win32") {
|
||||
@@ -151,7 +151,7 @@ program
|
||||
.join("\n");
|
||||
fs.writeFileSync(powershellEnvFile, powershellEnvFileContents);
|
||||
logger.info(`\nCodeQL environment output to "${jsonEnvFile}", "${batEnvFile}" and "${powershellEnvFile}". ` +
|
||||
`Please export these variables to future processes so that CodeQL can monitor the build. ` +
|
||||
`Please export these variables to future processes so the build can be traced. ` +
|
||||
`If using cmd/batch run "call ${batEnvFile}" ` +
|
||||
`or if using PowerShell run "cat ${powershellEnvFile} | Invoke-Expression".`);
|
||||
}
|
||||
@@ -160,11 +160,11 @@ program
|
||||
const shEnvFile = path.join(config.tempDir, "codeql-env.sh");
|
||||
const shEnvFileContents = Object.entries(tracerConfig.env)
|
||||
// Some vars contain ${LIB} that we do not want to be expanded when executing this script
|
||||
.map(([key, value]) => `export ${key}='${value.replace(/'/g, "'\"'\"'")}'`)
|
||||
.map(([key, value]) => `export ${key}="${value.replace(/\$/g, "\\$")}"`)
|
||||
.join("\n");
|
||||
fs.writeFileSync(shEnvFile, shEnvFileContents);
|
||||
logger.info(`\nCodeQL environment output to "${jsonEnvFile}" and "${shEnvFile}". ` +
|
||||
`Please export these variables to future processes so that CodeQL can monitor the build, ` +
|
||||
`Please export these variables to future processes so the build can be traced, ` +
|
||||
`for example by running ". ${shEnvFile}".`);
|
||||
}
|
||||
}
|
||||
@@ -217,8 +217,7 @@ program
|
||||
.requiredOption("--commit <commit>", "SHA of commit that was analyzed. (Required)")
|
||||
.requiredOption("--ref <ref>", "Name of ref that was analyzed. (Required)")
|
||||
.requiredOption("--github-url <url>", "URL of GitHub instance. (Required)")
|
||||
.option("--github-auth <auth>", "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead.")
|
||||
.option("--github-auth-stdin", "Read GitHub Apps token or personal access token from stdin.")
|
||||
.requiredOption("--github-auth <auth>", "GitHub Apps token or personal access token. (Required)")
|
||||
.option("--checkout-path <path>", "Checkout path. Default is the current working directory.")
|
||||
.option("--no-upload", "Do not upload results after analysis.")
|
||||
.option("--output-dir <dir>", "Directory to output SARIF files to. Default is in the temp directory.")
|
||||
@@ -227,30 +226,18 @@ program
|
||||
.option("--threads <threads>", "Number of threads to use when running queries. " +
|
||||
"Default is to use all available cores.")
|
||||
.option("--temp-dir <dir>", 'Directory to use for temporary files. Default is "./codeql-runner".')
|
||||
.option("--category <category>", "String used by Code Scanning for matching the analyses.")
|
||||
.option("--debug", "Print more verbose output", false)
|
||||
.action(async (cmd) => {
|
||||
const logger = logging_1.getRunnerLogger(cmd.debug);
|
||||
try {
|
||||
const tempDir = getTempDir(cmd.tempDir);
|
||||
const outputDir = cmd.outputDir || path.join(tempDir, "codeql-sarif");
|
||||
const config = await config_utils_1.getConfig(getTempDir(cmd.tempDir), logger);
|
||||
if (config === undefined) {
|
||||
throw new Error("Config file could not be found at expected location. " +
|
||||
"Was the 'init' command run with the same '--temp-dir' argument as this command.");
|
||||
}
|
||||
const auth = await util_1.getGitHubAuth(logger, cmd.githubAuth, cmd.githubAuthStdin);
|
||||
const apiDetails = {
|
||||
auth,
|
||||
url: util_1.parseGitHubUrl(cmd.githubUrl),
|
||||
};
|
||||
const outputDir = cmd.outputDir || path.join(config.tempDir, "codeql-sarif");
|
||||
const threads = util_1.getThreadsFlag(cmd.threads, logger);
|
||||
await analyze_1.runFinalize(outputDir, threads, config, logger);
|
||||
await analyze_1.runQueries(outputDir, util_1.getMemoryFlag(cmd.ram), util_1.getAddSnippetsFlag(cmd.addSnippets), threads, cmd.category, config, logger);
|
||||
if (!cmd.upload) {
|
||||
logger.info("Not uploading results");
|
||||
return;
|
||||
}
|
||||
await upload_lib.uploadFromRunner(outputDir, repository_1.parseRepositoryNwo(cmd.repository), cmd.commit, parseRef(cmd.ref), cmd.category, cmd.checkoutPath || process.cwd(), config.gitHubVersion, apiDetails, logger);
|
||||
await analyze_1.runAnalyze(repository_1.parseRepositoryNwo(cmd.repository), cmd.commit, parseRef(cmd.ref), undefined, undefined, undefined, cmd.checkoutPath || process.cwd(), undefined, cmd.githubAuth, parseGithubUrl(cmd.githubUrl), cmd.upload, "runner", outputDir, util_1.getMemoryFlag(cmd.ram), util_1.getAddSnippetsFlag(cmd.addSnippets), util_1.getThreadsFlag(cmd.threads, logger), config, logger);
|
||||
}
|
||||
catch (e) {
|
||||
logger.error("Analyze failed");
|
||||
@@ -266,21 +253,13 @@ program
|
||||
.requiredOption("--commit <commit>", "SHA of commit that was analyzed. (Required)")
|
||||
.requiredOption("--ref <ref>", "Name of ref that was analyzed. (Required)")
|
||||
.requiredOption("--github-url <url>", "URL of GitHub instance. (Required)")
|
||||
.option("--github-auth <auth>", "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead.")
|
||||
.option("--github-auth-stdin", "Read GitHub Apps token or personal access token from stdin.")
|
||||
.requiredOption("--github-auth <auth>", "GitHub Apps token or personal access token. (Required)")
|
||||
.option("--checkout-path <path>", "Checkout path. Default is the current working directory.")
|
||||
.option("--category <category>", "String used by Code Scanning for matching the analyses.")
|
||||
.option("--debug", "Print more verbose output", false)
|
||||
.action(async (cmd) => {
|
||||
const logger = logging_1.getRunnerLogger(cmd.debug);
|
||||
const auth = await util_1.getGitHubAuth(logger, cmd.githubAuth, cmd.githubAuthStdin);
|
||||
const apiDetails = {
|
||||
auth,
|
||||
url: util_1.parseGitHubUrl(cmd.githubUrl),
|
||||
};
|
||||
try {
|
||||
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
|
||||
await upload_lib.uploadFromRunner(cmd.sarifFile, repository_1.parseRepositoryNwo(cmd.repository), cmd.commit, parseRef(cmd.ref), cmd.category, cmd.checkoutPath || process.cwd(), gitHubVersion, apiDetails, logger);
|
||||
await upload_lib.upload(cmd.sarifFile, repository_1.parseRepositoryNwo(cmd.repository), cmd.commit, parseRef(cmd.ref), undefined, undefined, undefined, cmd.checkoutPath || process.cwd(), undefined, cmd.githubAuth, parseGithubUrl(cmd.githubUrl), "runner", logger);
|
||||
}
|
||||
catch (e) {
|
||||
logger.error("Upload failed");
|
||||
|
||||
File diff suppressed because one or more lines are too long
6
lib/testdata/testFile3.js
vendored
6
lib/testdata/testFile3.js
vendored
@@ -1,6 +0,0 @@
|
||||
"use strict";
|
||||
var a;
|
||||
var b;
|
||||
var c;
|
||||
var d;
|
||||
//# sourceMappingURL=testFile3.js.map
|
||||
1
lib/testdata/testFile3.js.map
vendored
1
lib/testdata/testFile3.js.map
vendored
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"testFile3.js","sourceRoot":"","sources":["../../src/testdata/testFile3.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,CAAC;AACN,IAAI,CAAC,CAAC;AACN,IAAI,CAAC,CAAC;AACN,IAAI,CAAC,CAAC"}
|
||||
7
lib/testing-utils.js
generated
7
lib/testing-utils.js
generated
@@ -72,11 +72,4 @@ function setupTests(test) {
|
||||
});
|
||||
}
|
||||
exports.setupTests = setupTests;
|
||||
// Sets environment variables that make using some libraries designed for
|
||||
// use only on actions safe to use outside of actions.
|
||||
function setupActionsVars(tempDir, toolsDir) {
|
||||
process.env["RUNNER_TEMP"] = tempDir;
|
||||
process.env["RUNNER_TOOL_CACHE"] = toolsDir;
|
||||
}
|
||||
exports.setupActionsVars = setupActionsVars;
|
||||
//# sourceMappingURL=testing-utils.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,kDAA0B;AAE1B,iDAAmC;AASnC,SAAS,UAAU,CAAC,OAAoB;IACtC,8CAA8C;IAC9C,gCAAgC;IAChC,2EAA2E;IAC3E,2FAA2F;IAC3F,OAAO,CACL,KAA0B,EAC1B,QAAiB,EACjB,EAA0B,EACjB,EAAE;QACX,2CAA2C;QAC3C,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;YACtD,EAAE,GAAG,QAAQ,CAAC;YACd,QAAQ,GAAG,SAAS,CAAC;SACtB;QAED,oBAAoB;QACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;SAC7B;aAAM;YACL,OAAO,CAAC,UAAU,IAAI,IAAI,WAAW,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SAC1E;QAED,iDAAiD;QACjD,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE;YAChD,EAAE,EAAE,CAAC;SACN;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,SAAgB,UAAU,CAAC,IAAwB;IACjD,MAAM,SAAS,GAAG,IAAkC,CAAC;IAErD,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE;QACzB,gEAAgE;QAChE,0CAA0C;QAC1C,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAErB,iEAAiE;QACjE,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC;QAC1B,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrE,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,kBAAkB,CAAC;QAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAQ,CAAC;QACpD,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrE,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,kBAAkB,CAAC;QAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAQ,CAAC;QAEpD,mEAAmE;QACnE,wEAAwE;QACxE,kEAAkE;QAClE,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;QACnB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,4BAA4B;QAC5B,0DAA0D;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7C,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;SAC5C;QAED,uCAAuC;QACvC,eAAK,CAAC,OAAO,EAAE,CAAC;QAEhB,oCAAoC;QACpC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC;AAvCD,gCAuCC"}
|
||||
269
lib/toolcache.js
generated
269
lib/toolcache.js
generated
@@ -1,269 +0,0 @@
|
||||
"use strict";
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const io = __importStar(require("@actions/io"));
|
||||
const actionsToolcache = __importStar(require("@actions/tool-cache"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const uuid_1 = require("uuid");
|
||||
const util_1 = require("./util");
|
||||
/*
|
||||
* This file acts as an interface to the functionality of the actions toolcache.
|
||||
* That library is not safe to use outside of actions as it makes assumptions about
|
||||
* the state of the filesystem and available environment variables.
|
||||
*
|
||||
* On actions we can just delegate to the toolcache library, however outside of
|
||||
* actions we provide our own implementation.
|
||||
*/
|
||||
/**
|
||||
* Extract a compressed tar archive.
|
||||
*
|
||||
* See extractTar function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
|
||||
*
|
||||
* @param file path to the tar
|
||||
* @param mode should run the actions or runner implementation
|
||||
* @param tempDir path to the temporary directory
|
||||
* @param logger logger to use
|
||||
* @returns path to the destination directory
|
||||
*/
|
||||
async function extractTar(file, tempDir, logger) {
|
||||
if (util_1.isActions()) {
|
||||
return await actionsToolcache.extractTar(file);
|
||||
}
|
||||
else {
|
||||
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
if (!file) {
|
||||
throw new Error("parameter 'file' is required");
|
||||
}
|
||||
// Create dest
|
||||
const dest = createExtractFolder(tempDir);
|
||||
// Determine whether GNU tar
|
||||
logger.debug("Checking tar --version");
|
||||
let versionOutput = "";
|
||||
await new toolrunner.ToolRunner(await safeWhich.safeWhich("tar"), ["--version"], {
|
||||
ignoreReturnCode: true,
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => (versionOutput += data.toString()),
|
||||
stderr: (data) => (versionOutput += data.toString()),
|
||||
},
|
||||
}).exec();
|
||||
logger.debug(versionOutput.trim());
|
||||
const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR");
|
||||
// Initialize args
|
||||
const args = ["xz"];
|
||||
if (logger.isDebug()) {
|
||||
args.push("-v");
|
||||
}
|
||||
let destArg = dest;
|
||||
let fileArg = file;
|
||||
if (process.platform === "win32" && isGnuTar) {
|
||||
args.push("--force-local");
|
||||
destArg = dest.replace(/\\/g, "/");
|
||||
// Technically only the dest needs to have `/` but for aesthetic consistency
|
||||
// convert slashes in the file arg too.
|
||||
fileArg = file.replace(/\\/g, "/");
|
||||
}
|
||||
if (isGnuTar) {
|
||||
// Suppress warnings when using GNU tar to extract archives created by BSD tar
|
||||
args.push("--warning=no-unknown-keyword");
|
||||
}
|
||||
args.push("-C", destArg, "-f", fileArg);
|
||||
await new toolrunner.ToolRunner(`tar`, args).exec();
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
exports.extractTar = extractTar;
|
||||
/**
|
||||
* Caches a directory and installs it into the tool cacheDir.
|
||||
*
|
||||
* Also see cacheDir function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
|
||||
*
|
||||
* @param sourceDir the directory to cache into tools
|
||||
* @param tool tool name
|
||||
* @param version version of the tool. semver format
|
||||
* @param mode should run the actions or runner implementation
|
||||
* @param toolCacheDir path to the tool cache directory
|
||||
* @param logger logger to use
|
||||
*/
|
||||
async function cacheDir(sourceDir, tool, version, toolCacheDir, logger) {
|
||||
if (util_1.isActions()) {
|
||||
return await actionsToolcache.cacheDir(sourceDir, tool, version);
|
||||
}
|
||||
else {
|
||||
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
version = semver.clean(version) || version;
|
||||
const arch = os.arch();
|
||||
logger.debug(`Caching tool ${tool} ${version} ${arch}`);
|
||||
logger.debug(`source dir: ${sourceDir}`);
|
||||
if (!fs.statSync(sourceDir).isDirectory()) {
|
||||
throw new Error("sourceDir is not a directory");
|
||||
}
|
||||
// Create the tool dir
|
||||
const destPath = createToolPath(tool, version, arch, toolCacheDir, logger);
|
||||
// copy each child item. do not move. move can fail on Windows
|
||||
// due to anti-virus software having an open handle on a file.
|
||||
for (const itemName of fs.readdirSync(sourceDir)) {
|
||||
const s = path.join(sourceDir, itemName);
|
||||
await io.cp(s, destPath, { recursive: true });
|
||||
}
|
||||
// write .complete
|
||||
completeToolPath(tool, version, arch, toolCacheDir, logger);
|
||||
return destPath;
|
||||
}
|
||||
}
|
||||
exports.cacheDir = cacheDir;
|
||||
/**
|
||||
* Finds the path to a tool version in the local installed tool cache.
|
||||
*
|
||||
* Also see find function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param versionSpec version of the tool
|
||||
* @param mode should run the actions or runner implementation
|
||||
* @param toolCacheDir path to the tool cache directory
|
||||
* @param logger logger to use
|
||||
*/
|
||||
function find(toolName, versionSpec, toolCacheDir, logger) {
|
||||
if (util_1.isActions()) {
|
||||
return actionsToolcache.find(toolName, versionSpec);
|
||||
}
|
||||
else {
|
||||
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
if (!toolName) {
|
||||
throw new Error("toolName parameter is required");
|
||||
}
|
||||
if (!versionSpec) {
|
||||
throw new Error("versionSpec parameter is required");
|
||||
}
|
||||
const arch = os.arch();
|
||||
// attempt to resolve an explicit version
|
||||
if (!isExplicitVersion(versionSpec, logger)) {
|
||||
const localVersions = findAllVersions(toolName, toolCacheDir, logger);
|
||||
const match = evaluateVersions(localVersions, versionSpec, logger);
|
||||
versionSpec = match;
|
||||
}
|
||||
// check for the explicit version in the cache
|
||||
let toolPath = "";
|
||||
if (versionSpec) {
|
||||
versionSpec = semver.clean(versionSpec) || "";
|
||||
const cachePath = path.join(toolCacheDir, toolName, versionSpec, arch);
|
||||
logger.debug(`checking cache: ${cachePath}`);
|
||||
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) {
|
||||
logger.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`);
|
||||
toolPath = cachePath;
|
||||
}
|
||||
else {
|
||||
logger.debug("not found");
|
||||
}
|
||||
}
|
||||
return toolPath;
|
||||
}
|
||||
}
|
||||
exports.find = find;
|
||||
/**
|
||||
* Finds the paths to all versions of a tool that are installed in the local tool cache.
|
||||
*
|
||||
* Also see findAllVersions function from node_modules/@actions/tool-cache/lib/tool-cache.d.ts
|
||||
*
|
||||
* @param toolName name of the tool
|
||||
* @param toolCacheDir path to the tool cache directory
|
||||
* @param logger logger to use
|
||||
*/
|
||||
function findAllVersions(toolName, toolCacheDir, logger) {
|
||||
if (util_1.isActions()) {
|
||||
return actionsToolcache.findAllVersions(toolName);
|
||||
}
|
||||
else {
|
||||
// Initial implementation copied from node_modules/@actions/tool-cache/lib/tool-cache.js
|
||||
const versions = [];
|
||||
const arch = os.arch();
|
||||
const toolPath = path.join(toolCacheDir, toolName);
|
||||
if (fs.existsSync(toolPath)) {
|
||||
const children = fs.readdirSync(toolPath);
|
||||
for (const child of children) {
|
||||
if (isExplicitVersion(child, logger)) {
|
||||
const fullPath = path.join(toolPath, child, arch || "");
|
||||
if (fs.existsSync(fullPath) &&
|
||||
fs.existsSync(`${fullPath}.complete`)) {
|
||||
versions.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
}
|
||||
exports.findAllVersions = findAllVersions;
|
||||
async function downloadTool(url, tempDir, headers) {
|
||||
const dest = path.join(tempDir, uuid_1.v4());
|
||||
const finalHeaders = Object.assign({ "User-Agent": "CodeQL Action" }, headers);
|
||||
return await actionsToolcache.downloadTool(url, dest, undefined, finalHeaders);
|
||||
}
|
||||
exports.downloadTool = downloadTool;
|
||||
function createExtractFolder(tempDir) {
|
||||
// create a temp dir
|
||||
const dest = path.join(tempDir, "toolcache-temp");
|
||||
if (!fs.existsSync(dest)) {
|
||||
fs.mkdirSync(dest);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
function createToolPath(tool, version, arch, toolCacheDir, logger) {
|
||||
const folderPath = path.join(toolCacheDir, tool, semver.clean(version) || version, arch || "");
|
||||
logger.debug(`destination ${folderPath}`);
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
fs.rmdirSync(folderPath, { recursive: true });
|
||||
fs.rmdirSync(markerPath, { recursive: true });
|
||||
fs.mkdirSync(folderPath, { recursive: true });
|
||||
return folderPath;
|
||||
}
|
||||
function completeToolPath(tool, version, arch, toolCacheDir, logger) {
|
||||
const folderPath = path.join(toolCacheDir, tool, semver.clean(version) || version, arch || "");
|
||||
const markerPath = `${folderPath}.complete`;
|
||||
fs.writeFileSync(markerPath, "");
|
||||
logger.debug("finished caching tool");
|
||||
}
|
||||
function isExplicitVersion(versionSpec, logger) {
|
||||
const c = semver.clean(versionSpec) || "";
|
||||
logger.debug(`isExplicit: ${c}`);
|
||||
const valid = semver.valid(c) != null;
|
||||
logger.debug(`explicit? ${valid}`);
|
||||
return valid;
|
||||
}
|
||||
function evaluateVersions(versions, versionSpec, logger) {
|
||||
let version = "";
|
||||
logger.debug(`evaluating ${versions.length} versions`);
|
||||
versions = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
for (let i = versions.length - 1; i >= 0; i--) {
|
||||
const potential = versions[i];
|
||||
const satisfied = semver.satisfies(potential, versionSpec);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (version) {
|
||||
logger.debug(`matched: ${version}`);
|
||||
}
|
||||
else {
|
||||
logger.debug("match not found");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
//# sourceMappingURL=toolcache.js.map
|
||||
File diff suppressed because one or more lines are too long
7
lib/toolrunner-error-catcher.js
generated
7
lib/toolrunner-error-catcher.js
generated
@@ -7,8 +7,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||
const toolrunnner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||
/**
|
||||
* Wrapper for toolrunner.Toolrunner which checks for specific return code and/or regex matches in console output.
|
||||
* Output will be streamed to the live console as well as captured for subsequent processing.
|
||||
@@ -51,7 +50,7 @@ async function toolrunnerErrorCatcher(commandLine, args, matchers, options) {
|
||||
// we capture the original return code or error so that if no match is found we can duplicate the behavior
|
||||
let returnState;
|
||||
try {
|
||||
returnState = await new toolrunner.ToolRunner(await safeWhich.safeWhich(commandLine), args, {
|
||||
returnState = await new toolrunnner.ToolRunner(commandLine, args, {
|
||||
...options,
|
||||
listeners,
|
||||
ignoreReturnCode: true,
|
||||
@@ -76,7 +75,7 @@ async function toolrunnerErrorCatcher(commandLine, args, matchers, options) {
|
||||
return returnState;
|
||||
}
|
||||
else {
|
||||
throw new Error(`The process '${commandLine}' failed with exit code ${returnState}`);
|
||||
throw new Error(`The process \'${commandLine}\' failed with exit code ${returnState}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"toolrunner-error-catcher.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.ts"],"names":[],"mappings":";;;;;;;;;AACA,yEAA2D;AAC3D,kEAAoD;AAIpD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,IAAe,EACf,QAAyB,EACzB,OAAwB;;IAExB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;KACF,CAAC;IAEF,0GAA0G;IAC1G,IAAI,WAA2B,CAAC;IAChC,IAAI;QACF,WAAW,GAAG,MAAM,IAAI,UAAU,CAAC,UAAU,CAC3C,MAAM,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,EACtC,IAAI,EACJ;YACE,GAAG,OAAO;YACV,SAAS;YACT,gBAAgB,EAAE,IAAI;SACvB,CACF,CAAC,IAAI,EAAE,CAAC;KACV;IAAC,OAAO,CAAC,EAAE;QACV,WAAW,GAAG,CAAC,CAAC;KACjB;IAED,mEAAmE;IACnE,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE1C,IAAI,QAAQ,EAAE;QACZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IACE,OAAO,CAAC,QAAQ,KAAK,WAAW,WAChC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,WACjC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,EACjC;gBACA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAClC;SACF;KACF;IAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;QACnC,qFAAqF;QACrF,UAAI,OAAO,0CAAE,gBAAgB,EAAE;YAC7B,OAAO,WAAW,CAAC;SACpB;aAAM;YACL,MAAM,IAAI,KAAK,CACb,gBAAgB,WAAW,2BAA2B,WAAW,EAAE,CACpE,CAAC;SACH;KACF;SAAM;QACL,MAAM,WAAW,CAAC;KACnB;AACH,CAAC;AAzED,wDAyEC"}
|
||||
{"version":3,"file":"toolrunner-error-catcher.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.ts"],"names":[],"mappings":";;;;;;;;;AACA,0EAA4D;AAI5D;;;;;;;;;;GAUG;AACI,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,IAAe,EACf,QAAyB,EACzB,OAAwB;;IAExB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,aAAA,OAAO,0CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;iBAAM;gBACL,4FAA4F;gBAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aAC5B;QACH,CAAC;KACF,CAAC;IAEF,0GAA0G;IAC1G,IAAI,WAA2B,CAAC;IAChC,IAAI;QACF,WAAW,GAAG,MAAM,IAAI,WAAW,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE;YAChE,GAAG,OAAO;YACV,SAAS;YACT,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAC,IAAI,EAAE,CAAC;KACX;IAAC,OAAO,CAAC,EAAE;QACV,WAAW,GAAG,CAAC,CAAC;KACjB;IAED,mEAAmE;IACnE,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE1C,IAAI,QAAQ,EAAE;QACZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IACE,OAAO,CAAC,QAAQ,KAAK,WAAW,WAChC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,WACjC,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,EAAC,EACjC;gBACA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAClC;SACF;KACF;IAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;QACnC,qFAAqF;QACrF,UAAI,OAAO,0CAAE,gBAAgB,EAAE;YAC7B,OAAO,WAAW,CAAC;SACpB;aAAM;YACL,MAAM,IAAI,KAAK,CACb,iBAAiB,WAAW,4BAA4B,WAAW,EAAE,CACtE,CAAC;SACH;KACF;SAAM;QACL,MAAM,WAAW,CAAC;KACnB;AACH,CAAC;AArED,wDAqEC"}
|
||||
60
lib/tracer-config.js
generated
60
lib/tracer-config.js
generated
@@ -13,13 +13,17 @@ const languages_1 = require("./languages");
|
||||
const util = __importStar(require("./util"));
|
||||
const CRITICAL_TRACER_VARS = new Set([
|
||||
"SEMMLE_PRELOAD_libtrace",
|
||||
,
|
||||
"SEMMLE_RUNNER",
|
||||
,
|
||||
"SEMMLE_COPY_EXECUTABLES_ROOT",
|
||||
,
|
||||
"SEMMLE_DEPTRACE_SOCKET",
|
||||
,
|
||||
"SEMMLE_JAVA_TOOL_OPTIONS",
|
||||
]);
|
||||
async function getTracerConfigForLanguage(codeql, config, language) {
|
||||
const env = await codeql.getTracerEnv(util.getCodeQLDatabasePath(config, language));
|
||||
const env = await codeql.getTracerEnv(util.getCodeQLDatabasePath(config.tempDir, language));
|
||||
const spec = env["ODASA_TRACER_CONFIGURATION"];
|
||||
const info = { spec, env: {} };
|
||||
// Extract critical tracer variables from the environment
|
||||
@@ -45,7 +49,7 @@ async function getTracerConfigForLanguage(codeql, config, language) {
|
||||
return info;
|
||||
}
|
||||
exports.getTracerConfigForLanguage = getTracerConfigForLanguage;
|
||||
function concatTracerConfigs(tracerConfigs, config, writeBothEnvironments = false) {
|
||||
function concatTracerConfigs(tracerConfigs, config) {
|
||||
// A tracer config is a map containing additional environment variables and a tracer 'spec' file.
|
||||
// A tracer 'spec' file has the following format [log_file, number_of_blocks, blocks_text]
|
||||
// Merge the environments
|
||||
@@ -103,42 +107,20 @@ function concatTracerConfigs(tracerConfigs, config, writeBothEnvironments = fals
|
||||
envSize += 1;
|
||||
}
|
||||
fs.writeFileSync(spec, newSpecContent.join("\n"));
|
||||
if (writeBothEnvironments || process.platform !== "win32") {
|
||||
// Prepare the content of the compound environment file on Unix
|
||||
let buffer = Buffer.alloc(4);
|
||||
buffer.writeInt32LE(envSize, 0);
|
||||
for (const e of Object.entries(env)) {
|
||||
const key = e[0];
|
||||
const value = e[1];
|
||||
const lineBuffer = Buffer.from(`${key}=${value}\0`, "utf8");
|
||||
const sizeBuffer = Buffer.alloc(4);
|
||||
sizeBuffer.writeInt32LE(lineBuffer.length, 0);
|
||||
buffer = Buffer.concat([buffer, sizeBuffer, lineBuffer]);
|
||||
}
|
||||
// Write the compound environment for Unix
|
||||
const envPath = `${spec}.environment`;
|
||||
fs.writeFileSync(envPath, buffer);
|
||||
}
|
||||
if (writeBothEnvironments || process.platform === "win32") {
|
||||
// Prepare the content of the compound environment file on Windows
|
||||
let bufferWindows = Buffer.alloc(0);
|
||||
let length = 0;
|
||||
for (const e of Object.entries(env)) {
|
||||
const key = e[0];
|
||||
const value = e[1];
|
||||
const string = `${key}=${value}\0`;
|
||||
length += string.length;
|
||||
const lineBuffer = Buffer.from(string, "utf16le");
|
||||
bufferWindows = Buffer.concat([bufferWindows, lineBuffer]);
|
||||
}
|
||||
// Prepare the content of the compound environment file
|
||||
let buffer = Buffer.alloc(4);
|
||||
buffer.writeInt32LE(envSize, 0);
|
||||
for (const e of Object.entries(env)) {
|
||||
const key = e[0];
|
||||
const value = e[1];
|
||||
const lineBuffer = new Buffer(`${key}=${value}\0`, "utf8");
|
||||
const sizeBuffer = Buffer.alloc(4);
|
||||
sizeBuffer.writeInt32LE(length + 1, 0); // Add one for trailing null character marking end
|
||||
const trailingNull = Buffer.from(`\0`, "utf16le");
|
||||
bufferWindows = Buffer.concat([sizeBuffer, bufferWindows, trailingNull]);
|
||||
// Write the compound environment for Windows
|
||||
const envPathWindows = `${spec}.win32env`;
|
||||
fs.writeFileSync(envPathWindows, bufferWindows);
|
||||
sizeBuffer.writeInt32LE(lineBuffer.length, 0);
|
||||
buffer = Buffer.concat([buffer, sizeBuffer, lineBuffer]);
|
||||
}
|
||||
// Write the compound environment
|
||||
const envPath = `${spec}.environment`;
|
||||
fs.writeFileSync(envPath, buffer);
|
||||
return { env, spec };
|
||||
}
|
||||
exports.concatTracerConfigs = concatTracerConfigs;
|
||||
@@ -163,12 +145,6 @@ async function getCombinedTracerConfig(config, codeql) {
|
||||
else if (process.platform !== "win32") {
|
||||
mainTracerConfig.env["LD_PRELOAD"] = path.join(codeQLDir, "tools", "linux64", "${LIB}trace.so");
|
||||
}
|
||||
// On macos it's necessary to prefix the build command with the runner executable
|
||||
// on order to trace when System Integrity Protection is enabled.
|
||||
// The executable also exists and works for other platforms so we output this env
|
||||
// var with a path to the runner regardless so it's always available.
|
||||
const runnerExeName = process.platform === "win32" ? "runner.exe" : "runner";
|
||||
mainTracerConfig.env["CODEQL_RUNNER"] = path.join(mainTracerConfig.env["CODEQL_DIST"], "tools", mainTracerConfig.env["CODEQL_PLATFORM"], runnerExeName);
|
||||
return mainTracerConfig;
|
||||
}
|
||||
exports.getCombinedTracerConfig = getCombinedTracerConfig;
|
||||
|
||||
File diff suppressed because one or more lines are too long
46
lib/tracer-config.test.js
generated
46
lib/tracer-config.test.js
generated
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
@@ -6,13 +9,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const codeql_1 = require("./codeql");
|
||||
const languages_1 = require("./languages");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
@@ -29,9 +29,6 @@ function getTestConfig(tmpDir) {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
gitHubVersion: { type: util.GitHubVariant.DOTCOM },
|
||||
dbLocation: path.resolve(tmpDir, "codeql_databases"),
|
||||
packs: {},
|
||||
};
|
||||
}
|
||||
// A very minimal setup
|
||||
@@ -61,6 +58,7 @@ ava_1.default("getTracerConfigForLanguage - existing / critical vars", async (t)
|
||||
process.env["SEMMLE_COPY_EXECUTABLES_ROOT"] = "abc";
|
||||
process.env["SEMMLE_DEPTRACE_SOCKET"] = "abc";
|
||||
process.env["SEMMLE_JAVA_TOOL_OPTIONS"] = "abc";
|
||||
process.env["SEMMLE_DEPTRACE_SOCKET"] = "abc";
|
||||
process.env["CODEQL_VAR"] = "abc";
|
||||
// Now CodeQL returns all these variables, and one more, with different values
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
@@ -218,26 +216,17 @@ ava_1.default("concatTracerConfigs - compound environment file is created correc
|
||||
foo: "bar_baz",
|
||||
},
|
||||
};
|
||||
const result = tracer_config_1.concatTracerConfigs({ javascript: tc1, python: tc2 }, config, true);
|
||||
// Check binary contents for the Unix file
|
||||
const result = tracer_config_1.concatTracerConfigs({ javascript: tc1, python: tc2 }, config);
|
||||
const envPath = `${result.spec}.environment`;
|
||||
t.true(fs.existsSync(envPath));
|
||||
const buffer = fs.readFileSync(envPath);
|
||||
// Contents is binary data
|
||||
t.deepEqual(buffer.length, 28);
|
||||
t.deepEqual(buffer.readInt32LE(0), 2); // number of env vars
|
||||
t.deepEqual(buffer.readInt32LE(4), 4); // length of env var definition
|
||||
t.deepEqual(buffer.toString("utf8", 8, 12), "a=a\0"); // [key]=[value]\0
|
||||
t.deepEqual(buffer.readInt32LE(12), 12); // length of env var definition
|
||||
t.deepEqual(buffer.toString("utf8", 16, 28), "foo=bar_baz\0"); // [key]=[value]\0
|
||||
// Check binary contents for the Windows file
|
||||
const envPathWindows = `${result.spec}.win32env`;
|
||||
t.true(fs.existsSync(envPathWindows));
|
||||
const bufferWindows = fs.readFileSync(envPathWindows);
|
||||
t.deepEqual(bufferWindows.length, 38);
|
||||
t.deepEqual(bufferWindows.readInt32LE(0), 4 + 12 + 1); // number of tchars to represent the environment
|
||||
t.deepEqual(bufferWindows.toString("utf16le", 4, 12), "a=a\0"); // [key]=[value]\0
|
||||
t.deepEqual(bufferWindows.toString("utf16le", 12, 36), "foo=bar_baz\0"); // [key]=[value]\0
|
||||
t.deepEqual(bufferWindows.toString("utf16le", 36, 38), "\0"); // trailing null character
|
||||
});
|
||||
});
|
||||
ava_1.default("getCombinedTracerConfig - return undefined when no languages are traced languages", async (t) => {
|
||||
@@ -249,7 +238,6 @@ ava_1.default("getCombinedTracerConfig - return undefined when no languages are
|
||||
async getTracerEnv() {
|
||||
return {
|
||||
ODASA_TRACER_CONFIGURATION: "abc",
|
||||
CODEQL_DIST: "/",
|
||||
foo: "bar",
|
||||
};
|
||||
},
|
||||
@@ -262,28 +250,17 @@ ava_1.default("getCombinedTracerConfig - valid spec file", async (t) => {
|
||||
const config = getTestConfig(tmpDir);
|
||||
const spec = path.join(tmpDir, "spec");
|
||||
fs.writeFileSync(spec, "foo.log\n2\nabc\ndef");
|
||||
const bundlePath = path.join(tmpDir, "bundle");
|
||||
const codeqlPlatform = process.platform === "win32"
|
||||
? "win64"
|
||||
: process.platform === "darwin"
|
||||
? "osx64"
|
||||
: "linux64";
|
||||
const codeQL = codeql_1.setCodeQL({
|
||||
async getTracerEnv() {
|
||||
return {
|
||||
ODASA_TRACER_CONFIGURATION: spec,
|
||||
CODEQL_DIST: bundlePath,
|
||||
CODEQL_PLATFORM: codeqlPlatform,
|
||||
foo: "bar",
|
||||
};
|
||||
},
|
||||
});
|
||||
const result = await tracer_config_1.getCombinedTracerConfig(config, codeQL);
|
||||
t.notDeepEqual(result, undefined);
|
||||
const expectedEnv = {
|
||||
foo: "bar",
|
||||
CODEQL_DIST: bundlePath,
|
||||
CODEQL_PLATFORM: codeqlPlatform,
|
||||
ODASA_TRACER_CONFIGURATION: result.spec,
|
||||
};
|
||||
if (process.platform === "darwin") {
|
||||
@@ -292,15 +269,6 @@ ava_1.default("getCombinedTracerConfig - valid spec file", async (t) => {
|
||||
else if (process.platform !== "win32") {
|
||||
expectedEnv["LD_PRELOAD"] = path.join(path.dirname(codeQL.getPath()), "tools", "linux64", "${LIB}trace.so");
|
||||
}
|
||||
if (process.platform === "win32") {
|
||||
expectedEnv["CODEQL_RUNNER"] = path.join(bundlePath, "tools/win64/runner.exe");
|
||||
}
|
||||
else if (process.platform === "darwin") {
|
||||
expectedEnv["CODEQL_RUNNER"] = path.join(bundlePath, "tools/osx64/runner");
|
||||
}
|
||||
else {
|
||||
expectedEnv["CODEQL_RUNNER"] = path.join(bundlePath, "tools/linux64/runner");
|
||||
}
|
||||
t.deepEqual(result, {
|
||||
spec: path.join(tmpDir, "compound-spec"),
|
||||
env: expectedEnv,
|
||||
|
||||
File diff suppressed because one or more lines are too long
194
lib/upload-lib.js
generated
194
lib/upload-lib.js
generated
@@ -10,17 +10,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const zlib_1 = __importDefault(require("zlib"));
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const file_url_1 = __importDefault(require("file-url"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const jsonschema = __importStar(require("jsonschema"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const path = __importStar(require("path"));
|
||||
const zlib_1 = __importDefault(require("zlib"));
|
||||
const api = __importStar(require("./api-client"));
|
||||
const fingerprints = __importStar(require("./fingerprints"));
|
||||
const repository_1 = require("./repository");
|
||||
const sharedEnv = __importStar(require("./shared-environment"));
|
||||
const util = __importStar(require("./util"));
|
||||
// Takes a list of paths to sarif files and combines them together,
|
||||
@@ -37,52 +34,24 @@ function combineSarifFiles(sarifFiles) {
|
||||
combinedSarif.version = sarifObject.version;
|
||||
}
|
||||
else if (combinedSarif.version !== sarifObject.version) {
|
||||
throw new Error(`Different SARIF versions encountered: ${combinedSarif.version} and ${sarifObject.version}`);
|
||||
throw `Different SARIF versions encountered: ${combinedSarif.version} and ${sarifObject.version}`;
|
||||
}
|
||||
combinedSarif.runs.push(...sarifObject.runs);
|
||||
}
|
||||
return JSON.stringify(combinedSarif);
|
||||
}
|
||||
exports.combineSarifFiles = combineSarifFiles;
|
||||
// Populates the run.automationDetails.id field using the analysis_key and environment
|
||||
// and return an updated sarif file contents.
|
||||
function populateRunAutomationDetails(sarifContents, category, analysis_key, environment) {
|
||||
if (analysis_key === undefined) {
|
||||
return sarifContents;
|
||||
}
|
||||
const automationID = getAutomationID(category, analysis_key, environment);
|
||||
const sarif = JSON.parse(sarifContents);
|
||||
for (const run of sarif.runs || []) {
|
||||
if (run.automationDetails === undefined) {
|
||||
run.automationDetails = {
|
||||
id: automationID,
|
||||
};
|
||||
}
|
||||
}
|
||||
return JSON.stringify(sarif);
|
||||
}
|
||||
exports.populateRunAutomationDetails = populateRunAutomationDetails;
|
||||
function getAutomationID(category, analysis_key, environment) {
|
||||
if (category !== undefined) {
|
||||
let automationID = category;
|
||||
if (!automationID.endsWith("/")) {
|
||||
automationID += "/";
|
||||
}
|
||||
return automationID;
|
||||
}
|
||||
return actionsUtil.computeAutomationID(analysis_key, environment);
|
||||
}
|
||||
// Upload the given payload.
|
||||
// If the request fails then this will retry a small number of times.
|
||||
async function uploadPayload(payload, repositoryNwo, apiDetails, logger) {
|
||||
async function uploadPayload(payload, repositoryNwo, githubAuth, githubUrl, mode, logger) {
|
||||
logger.info("Uploading results");
|
||||
// If in test mode we don't want to upload the results
|
||||
const testMode = process.env["TEST_MODE"] === "true" || false;
|
||||
if (testMode) {
|
||||
return;
|
||||
}
|
||||
const client = api.getApiClient(apiDetails);
|
||||
const reqURL = util.isActions()
|
||||
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, {
|
||||
@@ -93,72 +62,36 @@ async function uploadPayload(payload, repositoryNwo, apiDetails, logger) {
|
||||
logger.debug(`response status: ${response.status}`);
|
||||
logger.info("Successfully uploaded results");
|
||||
}
|
||||
// Recursively walks a directory and returns all SARIF files it finds.
|
||||
// Does not follow symlinks.
|
||||
function findSarifFilesInDir(sarifPath) {
|
||||
// Uploads a single sarif file or a directory of sarif files
|
||||
// depending on what the path happens to refer to.
|
||||
// Returns true iff the upload occurred and succeeded
|
||||
async function upload(sarifPath, repositoryNwo, commitOid, ref, analysisKey, analysisName, workflowRunID, checkoutPath, environment, githubAuth, githubUrl, mode, logger) {
|
||||
const sarifFiles = [];
|
||||
const walkSarifFiles = (dir) => {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile() && entry.name.endsWith(".sarif")) {
|
||||
sarifFiles.push(path.resolve(dir, entry.name));
|
||||
}
|
||||
else if (entry.isDirectory()) {
|
||||
walkSarifFiles(path.resolve(dir, entry.name));
|
||||
}
|
||||
}
|
||||
};
|
||||
walkSarifFiles(sarifPath);
|
||||
return sarifFiles;
|
||||
}
|
||||
exports.findSarifFilesInDir = findSarifFilesInDir;
|
||||
// Uploads a single sarif file or a directory of sarif files
|
||||
// depending on what the path happens to refer to.
|
||||
// Returns true iff the upload occurred and succeeded
|
||||
async function uploadFromActions(sarifPath, gitHubVersion, apiDetails, logger) {
|
||||
return await uploadFiles(getSarifFilePaths(sarifPath), repository_1.parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(), await actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getOptionalInput("category"), util.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), gitHubVersion, apiDetails, logger);
|
||||
}
|
||||
exports.uploadFromActions = uploadFromActions;
|
||||
// Uploads a single sarif file or a directory of sarif files
|
||||
// depending on what the path happens to refer to.
|
||||
// Returns true iff the upload occurred and succeeded
|
||||
async function uploadFromRunner(sarifPath, repositoryNwo, commitOid, ref, category, checkoutPath, gitHubVersion, apiDetails, logger) {
|
||||
return await uploadFiles(getSarifFilePaths(sarifPath), repositoryNwo, commitOid, ref, undefined, category, undefined, undefined, checkoutPath, undefined, gitHubVersion, apiDetails, logger);
|
||||
}
|
||||
exports.uploadFromRunner = uploadFromRunner;
|
||||
function getSarifFilePaths(sarifPath) {
|
||||
if (!fs.existsSync(sarifPath)) {
|
||||
throw new Error(`Path does not exist: ${sarifPath}`);
|
||||
}
|
||||
let sarifFiles;
|
||||
if (fs.lstatSync(sarifPath).isDirectory()) {
|
||||
sarifFiles = findSarifFilesInDir(sarifPath);
|
||||
const paths = fs
|
||||
.readdirSync(sarifPath)
|
||||
.filter((f) => f.endsWith(".sarif"))
|
||||
.map((f) => path.resolve(sarifPath, f));
|
||||
for (const path of paths) {
|
||||
sarifFiles.push(path);
|
||||
}
|
||||
if (sarifFiles.length === 0) {
|
||||
throw new Error(`No SARIF files found to upload in "${sarifPath}".`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sarifFiles = [sarifPath];
|
||||
sarifFiles.push(sarifPath);
|
||||
}
|
||||
return sarifFiles;
|
||||
return await uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, analysisName, workflowRunID, checkoutPath, environment, githubAuth, githubUrl, mode, logger);
|
||||
}
|
||||
exports.upload = upload;
|
||||
// Counts the number of results in the given SARIF file
|
||||
function countResultsInSarif(sarif) {
|
||||
let numResults = 0;
|
||||
let parsedSarif;
|
||||
try {
|
||||
parsedSarif = JSON.parse(sarif);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Invalid SARIF. JSON syntax error: ${e.message}`);
|
||||
}
|
||||
if (!Array.isArray(parsedSarif.runs)) {
|
||||
throw new Error("Invalid SARIF. Missing 'runs' array.");
|
||||
}
|
||||
for (const run of parsedSarif.runs) {
|
||||
if (!Array.isArray(run.results)) {
|
||||
throw new Error("Invalid SARIF. Missing 'results' array in run.");
|
||||
}
|
||||
for (const run of JSON.parse(sarif).runs) {
|
||||
numResults += run.results.length;
|
||||
}
|
||||
return numResults;
|
||||
@@ -184,53 +117,11 @@ function validateSarifFileSchema(sarifFilePath, logger) {
|
||||
}
|
||||
}
|
||||
exports.validateSarifFileSchema = validateSarifFileSchema;
|
||||
// buildPayload constructs a map ready to be uploaded to the API from the given
|
||||
// parameters, respecting the current mode and target GitHub instance version.
|
||||
function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion) {
|
||||
if (util.isActions()) {
|
||||
const payloadObj = {
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
analysis_key: analysisKey,
|
||||
analysis_name: analysisName,
|
||||
sarif: zippedSarif,
|
||||
workflow_run_id: workflowRunID,
|
||||
checkout_uri: checkoutURI,
|
||||
environment,
|
||||
started_at: process.env[sharedEnv.CODEQL_WORKFLOW_STARTED_AT],
|
||||
tool_names: toolNames,
|
||||
base_ref: undefined,
|
||||
base_sha: undefined,
|
||||
};
|
||||
// This behaviour can be made the default when support for GHES 3.0 is discontinued.
|
||||
if (gitHubVersion.type !== util.GitHubVariant.GHES ||
|
||||
semver.satisfies(gitHubVersion.version, `>=3.1`)) {
|
||||
if (process.env.GITHUB_EVENT_NAME === "pull_request" &&
|
||||
process.env.GITHUB_EVENT_PATH) {
|
||||
const githubEvent = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"));
|
||||
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
|
||||
payloadObj.base_sha = githubEvent.pull_request.base.sha;
|
||||
}
|
||||
}
|
||||
return payloadObj;
|
||||
}
|
||||
else {
|
||||
return {
|
||||
commit_sha: commitOid,
|
||||
ref,
|
||||
sarif: zippedSarif,
|
||||
checkout_uri: checkoutURI,
|
||||
tool_name: toolNames[0],
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.buildPayload = buildPayload;
|
||||
// Uploads the given set of sarif files.
|
||||
// Returns true iff the upload occurred and succeeded
|
||||
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, checkoutPath, environment, gitHubVersion, apiDetails, logger) {
|
||||
logger.startGroup("Uploading results");
|
||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||
if (util.isActions()) {
|
||||
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, analysisName, workflowRunID, checkoutPath, environment, githubAuth, githubUrl, mode, logger) {
|
||||
logger.info(`Uploading sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||
if (mode === "actions") {
|
||||
// This check only works on actions as env vars don't persist between calls to the runner
|
||||
const sentinelEnvVar = "CODEQL_UPLOAD_SARIF";
|
||||
if (process.env[sentinelEnvVar]) {
|
||||
@@ -243,22 +134,43 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
|
||||
validateSarifFileSchema(file, logger);
|
||||
}
|
||||
let sarifPayload = combineSarifFiles(sarifFiles);
|
||||
sarifPayload = await fingerprints.addFingerprints(sarifPayload, checkoutPath, logger);
|
||||
sarifPayload = populateRunAutomationDetails(sarifPayload, category, analysisKey, environment);
|
||||
const zippedSarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
|
||||
sarifPayload = fingerprints.addFingerprints(sarifPayload, checkoutPath, logger);
|
||||
const zipped_sarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
|
||||
const checkoutURI = file_url_1.default(checkoutPath);
|
||||
const toolNames = util.getToolNames(sarifPayload);
|
||||
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion);
|
||||
let payload;
|
||||
if (mode === "actions") {
|
||||
payload = JSON.stringify({
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
analysis_key: analysisKey,
|
||||
analysis_name: analysisName,
|
||||
sarif: zipped_sarif,
|
||||
workflow_run_id: workflowRunID,
|
||||
checkout_uri: checkoutURI,
|
||||
environment,
|
||||
started_at: process.env[sharedEnv.CODEQL_WORKFLOW_STARTED_AT],
|
||||
tool_names: toolNames,
|
||||
});
|
||||
}
|
||||
else {
|
||||
payload = JSON.stringify({
|
||||
commit_sha: commitOid,
|
||||
ref,
|
||||
sarif: zipped_sarif,
|
||||
checkout_uri: checkoutURI,
|
||||
tool_name: toolNames[0],
|
||||
});
|
||||
}
|
||||
// Log some useful debug info about the info
|
||||
const rawUploadSizeBytes = sarifPayload.length;
|
||||
logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`);
|
||||
const zippedUploadSizeBytes = zippedSarif.length;
|
||||
const zippedUploadSizeBytes = zipped_sarif.length;
|
||||
logger.debug(`Base64 zipped upload size: ${zippedUploadSizeBytes} bytes`);
|
||||
const numResultInSarif = countResultsInSarif(sarifPayload);
|
||||
logger.debug(`Number of results in upload: ${numResultInSarif}`);
|
||||
// Make the upload
|
||||
await uploadPayload(payload, repositoryNwo, apiDetails, logger);
|
||||
logger.endGroup();
|
||||
await uploadPayload(payload, repositoryNwo, githubAuth, githubUrl, mode, logger);
|
||||
return {
|
||||
raw_upload_size_bytes: rawUploadSizeBytes,
|
||||
zipped_upload_size_bytes: zippedUploadSizeBytes,
|
||||
|
||||
File diff suppressed because one or more lines are too long
84
lib/upload-lib.test.js
generated
84
lib/upload-lib.test.js
generated
@@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
@@ -6,21 +9,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
const ava_1 = __importDefault(require("ava"));
|
||||
const logging_1 = require("./logging");
|
||||
const testing_utils_1 = require("./testing-utils");
|
||||
const uploadLib = __importStar(require("./upload-lib"));
|
||||
const util_1 = require("./util");
|
||||
testing_utils_1.setupTests(ava_1.default);
|
||||
ava_1.default.beforeEach(() => {
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, "1.2.3");
|
||||
});
|
||||
ava_1.default("validateSarifFileSchema - valid", (t) => {
|
||||
const inputFile = `${__dirname}/../src/testdata/valid-sarif.sarif`;
|
||||
t.notThrows(() => uploadLib.validateSarifFileSchema(inputFile, logging_1.getRunnerLogger(true)));
|
||||
@@ -29,76 +23,4 @@ ava_1.default("validateSarifFileSchema - invalid", (t) => {
|
||||
const inputFile = `${__dirname}/../src/testdata/invalid-sarif.sarif`;
|
||||
t.throws(() => uploadLib.validateSarifFileSchema(inputFile, logging_1.getRunnerLogger(true)));
|
||||
});
|
||||
ava_1.default("validate correct payload used per version", async (t) => {
|
||||
const newVersions = [
|
||||
{ type: util_1.GitHubVariant.DOTCOM },
|
||||
{ type: util_1.GitHubVariant.GHES, version: "3.1.0" },
|
||||
];
|
||||
const oldVersions = [
|
||||
{ type: util_1.GitHubVariant.GHES, version: "2.22.1" },
|
||||
{ type: util_1.GitHubVariant.GHES, version: "3.0.0" },
|
||||
];
|
||||
const allVersions = newVersions.concat(oldVersions);
|
||||
process.env["GITHUB_EVENT_NAME"] = "push";
|
||||
for (const version of allVersions) {
|
||||
const payload = uploadLib.buildPayload("commit", "refs/heads/master", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
|
||||
// Not triggered by a pull request
|
||||
t.falsy(payload.base_ref);
|
||||
t.falsy(payload.base_sha);
|
||||
}
|
||||
process.env["GITHUB_EVENT_NAME"] = "pull_request";
|
||||
process.env["GITHUB_EVENT_PATH"] = `${__dirname}/../src/testdata/pull_request.json`;
|
||||
for (const version of newVersions) {
|
||||
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
|
||||
t.deepEqual(payload.base_ref, "refs/heads/master");
|
||||
t.deepEqual(payload.base_sha, "f95f852bd8fca8fcc58a9a2d6c842781e32a215e");
|
||||
}
|
||||
for (const version of oldVersions) {
|
||||
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version);
|
||||
// These older versions won't expect these values
|
||||
t.falsy(payload.base_ref);
|
||||
t.falsy(payload.base_sha);
|
||||
}
|
||||
});
|
||||
ava_1.default("finding SARIF files", async (t) => {
|
||||
await util_1.withTmpDir(async (tmpDir) => {
|
||||
// include a couple of sarif files
|
||||
fs.writeFileSync(path.join(tmpDir, "a.sarif"), "");
|
||||
fs.writeFileSync(path.join(tmpDir, "b.sarif"), "");
|
||||
// other random files shouldn't be returned
|
||||
fs.writeFileSync(path.join(tmpDir, "c.foo"), "");
|
||||
// we should recursively look in subdirectories
|
||||
fs.mkdirSync(path.join(tmpDir, "dir1"));
|
||||
fs.writeFileSync(path.join(tmpDir, "dir1", "d.sarif"), "");
|
||||
fs.mkdirSync(path.join(tmpDir, "dir1", "dir2"));
|
||||
fs.writeFileSync(path.join(tmpDir, "dir1", "dir2", "e.sarif"), "");
|
||||
// we should ignore symlinks
|
||||
fs.mkdirSync(path.join(tmpDir, "dir3"));
|
||||
fs.symlinkSync(tmpDir, path.join(tmpDir, "dir3", "symlink1"), "dir");
|
||||
fs.symlinkSync(path.join(tmpDir, "a.sarif"), path.join(tmpDir, "dir3", "symlink2.sarif"), "file");
|
||||
const sarifFiles = uploadLib.findSarifFilesInDir(tmpDir);
|
||||
t.deepEqual(sarifFiles, [
|
||||
path.join(tmpDir, "a.sarif"),
|
||||
path.join(tmpDir, "b.sarif"),
|
||||
path.join(tmpDir, "dir1", "d.sarif"),
|
||||
path.join(tmpDir, "dir1", "dir2", "e.sarif"),
|
||||
]);
|
||||
});
|
||||
});
|
||||
ava_1.default("populateRunAutomationDetails", (t) => {
|
||||
let sarif = '{"runs": [{}]}';
|
||||
const analysisKey = ".github/workflows/codeql-analysis.yml:analyze";
|
||||
let expectedSarif = '{"runs":[{"automationDetails":{"id":"language:javascript/os:linux/"}}]}';
|
||||
// Category has priority over analysis_key/environment
|
||||
let modifiedSarif = uploadLib.populateRunAutomationDetails(sarif, "language:javascript/os:linux", analysisKey, '{"language": "other", "os": "other"}');
|
||||
t.deepEqual(modifiedSarif, expectedSarif);
|
||||
// It doesn't matter if the category has a slash at the end or not
|
||||
modifiedSarif = uploadLib.populateRunAutomationDetails(sarif, "language:javascript/os:linux/", analysisKey, "");
|
||||
t.deepEqual(modifiedSarif, expectedSarif);
|
||||
// check that the automation details doesn't get overwritten
|
||||
sarif = '{"runs":[{"automationDetails":{"id":"my_id"}}]}';
|
||||
expectedSarif = '{"runs":[{"automationDetails":{"id":"my_id"}}]}';
|
||||
modifiedSarif = uploadLib.populateRunAutomationDetails(sarif, undefined, analysisKey, '{"os": "linux", "language": "javascript"}');
|
||||
t.deepEqual(modifiedSarif, expectedSarif);
|
||||
});
|
||||
//# sourceMappingURL=upload-lib.test.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"upload-lib.test.js","sourceRoot":"","sources":["../src/upload-lib.test.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"upload-lib.test.js","sourceRoot":"","sources":["../src/upload-lib.test.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAuB;AAEvB,uCAA4C;AAC5C,mDAA6C;AAC7C,wDAA0C;AAE1C,0BAAU,CAAC,aAAI,CAAC,CAAC;AAEjB,aAAI,CAAC,iCAAiC,EAAE,CAAC,CAAC,EAAE,EAAE;IAC5C,MAAM,SAAS,GAAG,GAAG,SAAS,oCAAoC,CAAC;IACnE,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CACf,SAAS,CAAC,uBAAuB,CAAC,SAAS,EAAE,yBAAe,CAAC,IAAI,CAAC,CAAC,CACpE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,EAAE,EAAE;IAC9C,MAAM,SAAS,GAAG,GAAG,SAAS,sCAAsC,CAAC;IACrE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CACZ,SAAS,CAAC,uBAAuB,CAAC,SAAS,EAAE,yBAAe,CAAC,IAAI,CAAC,CAAC,CACpE,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
||||
28
lib/upload-sarif-action.js
generated
28
lib/upload-sarif-action.js
generated
@@ -10,10 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const actionsUtil = __importStar(require("./actions-util"));
|
||||
const logging_1 = require("./logging");
|
||||
const repository_1 = require("./repository");
|
||||
const upload_lib = __importStar(require("./upload-lib"));
|
||||
const util_1 = require("./util");
|
||||
// eslint-disable-next-line import/no-commonjs
|
||||
const pkg = require("../package.json");
|
||||
async function sendSuccessStatusReport(startedAt, uploadStats) {
|
||||
const statusReportBase = await actionsUtil.createStatusReportBase("upload-sarif", "success", startedAt);
|
||||
const statusReport = {
|
||||
@@ -23,18 +21,12 @@ async function sendSuccessStatusReport(startedAt, uploadStats) {
|
||||
await actionsUtil.sendStatusReport(statusReport);
|
||||
}
|
||||
async function run() {
|
||||
util_1.initializeEnvironment(util_1.Mode.actions, pkg.version);
|
||||
const startedAt = new Date();
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("upload-sarif", "starting", startedAt)))) {
|
||||
if (!(await actionsUtil.sendStatusReport(await actionsUtil.createStatusReportBase("upload-sarif", "starting", startedAt), true))) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const apiDetails = {
|
||||
auth: actionsUtil.getRequiredInput("token"),
|
||||
url: util_1.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
const gitHubVersion = await util_1.getGitHubVersion(apiDetails);
|
||||
const uploadStats = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), gitHubVersion, apiDetails, logging_1.getActionsLogger());
|
||||
const uploadStats = await upload_lib.upload(actionsUtil.getRequiredInput("sarif_file"), repository_1.parseRepositoryNwo(actionsUtil.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(), actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), actionsUtil.getRequiredInput("token"), actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"), "actions", logging_1.getActionsLogger());
|
||||
await sendSuccessStatusReport(startedAt, uploadStats);
|
||||
}
|
||||
catch (error) {
|
||||
@@ -44,14 +36,8 @@ async function run() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
async function runWrapper() {
|
||||
try {
|
||||
await run();
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(`codeql/upload-sarif action failed: ${error}`);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
void runWrapper();
|
||||
run().catch((e) => {
|
||||
core.setFailed(`codeql/upload-sarif action failed: ${e}`);
|
||||
console.log(e);
|
||||
});
|
||||
//# sourceMappingURL=upload-sarif-action.js.map
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,uCAA6C;AAC7C,yDAA2C;AAC3C,iCAKgB;AAEhB,8CAA8C;AAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAMvC,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,WAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,cAAc,EACd,SAAS,EACT,SAAS,CACV,CAAC;IACF,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAG,WAAW;KACf,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,4BAAqB,CAAC,WAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,UAAU,EACV,SAAS,CACV,CACF,CAAC,EACF;QACA,OAAO;KACR;IAED,IAAI;QACF,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;YAC3C,GAAG,EAAE,0BAAmB,CAAC,mBAAmB,CAAC;SAC9C,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,uBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACpD,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAC1C,aAAa,EACb,UAAU,EACV,0BAAgB,EAAE,CACnB,CAAC;QACF,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KACvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,WAAW,CAAC,gBAAgB,CAChC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;KACR;AACH,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,GAAG,EAAE,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
|
||||
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,uCAA6C;AAC7C,6CAAkD;AAClD,yDAA2C;AAM3C,KAAK,UAAU,uBAAuB,CACpC,SAAe,EACf,WAA0C;IAE1C,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,sBAAsB,CAC/D,cAAc,EACd,SAAS,EACT,SAAS,CACV,CAAC;IACF,MAAM,YAAY,GAA4B;QAC5C,GAAG,gBAAgB;QACnB,GAAG,WAAW;KACf,CAAC;IACF,MAAM,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAClC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,UAAU,EACV,SAAS,CACV,EACD,IAAI,CACL,CAAC,EACF;QACA,OAAO;KACR;IAED,IAAI;QACF,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,MAAM,CACzC,WAAW,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAC1C,+BAAkB,CAAC,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,EACxE,MAAM,WAAW,CAAC,YAAY,EAAE,EAChC,WAAW,CAAC,MAAM,EAAE,EACpB,MAAM,WAAW,CAAC,cAAc,EAAE,EAClC,WAAW,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,EAClD,WAAW,CAAC,gBAAgB,EAAE,EAC9B,WAAW,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAC7C,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EACtC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,EACrC,WAAW,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,EACpD,SAAS,EACT,0BAAgB,EAAE,CACnB,CAAC;QACF,MAAM,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KACvD;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,WAAW,CAAC,gBAAgB,CAChC,MAAM,WAAW,CAAC,sBAAsB,CACtC,cAAc,EACd,SAAS,EACT,SAAS,EACT,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,KAAK,CACZ,CACF,CAAC;QACF,OAAO;KACR;AACH,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAChB,IAAI,CAAC,SAAS,CAAC,sCAAsC,CAAC,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
||||
305
lib/util.js
generated
305
lib/util.js
generated
@@ -10,10 +10,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = __importStar(require("fs"));
|
||||
const os = __importStar(require("os"));
|
||||
const path = __importStar(require("path"));
|
||||
const core = __importStar(require("@actions/core"));
|
||||
const semver = __importStar(require("semver"));
|
||||
const api_client_1 = require("./api-client");
|
||||
const apiCompatibility = __importStar(require("./api-compatibility.json"));
|
||||
/**
|
||||
* The URL for github.com.
|
||||
*/
|
||||
@@ -35,6 +31,12 @@ function getExtraOptionsEnvParam() {
|
||||
}
|
||||
}
|
||||
exports.getExtraOptionsEnvParam = getExtraOptionsEnvParam;
|
||||
function isLocalRun() {
|
||||
return (!!process.env.CODEQL_LOCAL_RUN &&
|
||||
process.env.CODEQL_LOCAL_RUN !== "false" &&
|
||||
process.env.CODEQL_LOCAL_RUN !== "0");
|
||||
}
|
||||
exports.isLocalRun = isLocalRun;
|
||||
/**
|
||||
* Get the array of all the tool names contained in the given sarif contents.
|
||||
*
|
||||
@@ -66,21 +68,9 @@ async function withTmpDir(body) {
|
||||
return result;
|
||||
}
|
||||
exports.withTmpDir = withTmpDir;
|
||||
/**
|
||||
* Gets an OS-specific amount of memory (in MB) to reserve for OS processes
|
||||
* when the user doesn't explicitly specify a memory setting.
|
||||
* This is a heuristic to avoid OOM errors (exit code 137 / SIGKILL)
|
||||
* from committing too much of the available memory to CodeQL.
|
||||
* @returns number
|
||||
*/
|
||||
function getSystemReservedMemoryMegaBytes() {
|
||||
// Windows needs more memory for OS processes.
|
||||
return 1024 * (process.platform === "win32" ? 1.5 : 1);
|
||||
}
|
||||
/**
|
||||
* Get the codeql `--ram` flag as configured by the `ram` input. If no value was
|
||||
* specified, the total available memory will be used minus a threshold
|
||||
* reserved for the OS.
|
||||
* specified, the total available memory will be used minus 256 MB.
|
||||
*
|
||||
* @returns string
|
||||
*/
|
||||
@@ -95,8 +85,8 @@ function getMemoryFlag(userInput) {
|
||||
else {
|
||||
const totalMemoryBytes = os.totalmem();
|
||||
const totalMemoryMegaBytes = totalMemoryBytes / (1024 * 1024);
|
||||
const reservedMemoryMegaBytes = getSystemReservedMemoryMegaBytes();
|
||||
memoryToUseMegaBytes = totalMemoryMegaBytes - reservedMemoryMegaBytes;
|
||||
const systemReservedMemoryMegaBytes = 256;
|
||||
memoryToUseMegaBytes = totalMemoryMegaBytes - systemReservedMemoryMegaBytes;
|
||||
}
|
||||
return `--ram=${Math.floor(memoryToUseMegaBytes)}`;
|
||||
}
|
||||
@@ -147,277 +137,18 @@ function getThreadsFlag(userInput, logger) {
|
||||
return `--threads=${numThreads}`;
|
||||
}
|
||||
exports.getThreadsFlag = getThreadsFlag;
|
||||
/**
|
||||
* Get the directory where CodeQL databases should be placed.
|
||||
*/
|
||||
function getCodeQLDatabasesDir(tempDir) {
|
||||
return path.resolve(tempDir, "codeql_databases");
|
||||
}
|
||||
exports.getCodeQLDatabasesDir = getCodeQLDatabasesDir;
|
||||
/**
|
||||
* Get the path where the CodeQL database for the given language lives.
|
||||
*/
|
||||
function getCodeQLDatabasePath(config, language) {
|
||||
return path.resolve(config.dbLocation, language);
|
||||
function getCodeQLDatabasePath(tempDir, language) {
|
||||
return path.resolve(getCodeQLDatabasesDir(tempDir), language);
|
||||
}
|
||||
exports.getCodeQLDatabasePath = getCodeQLDatabasePath;
|
||||
/**
|
||||
* Parses user input of a github.com or GHES URL to a canonical form.
|
||||
* Removes any API prefix or suffix if one is present.
|
||||
*/
|
||||
function parseGitHubUrl(inputUrl) {
|
||||
const originalUrl = inputUrl;
|
||||
if (inputUrl.indexOf("://") === -1) {
|
||||
inputUrl = `https://${inputUrl}`;
|
||||
}
|
||||
if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
|
||||
throw new Error(`"${originalUrl}" is not a http or https URL`);
|
||||
}
|
||||
let url;
|
||||
try {
|
||||
url = new URL(inputUrl);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`"${originalUrl}" is not a valid URL`);
|
||||
}
|
||||
// If we detect this is trying to be to github.com
|
||||
// then return with a fixed canonical URL.
|
||||
if (url.hostname === "github.com" || url.hostname === "api.github.com") {
|
||||
return exports.GITHUB_DOTCOM_URL;
|
||||
}
|
||||
// Remove the API prefix if it's present
|
||||
if (url.pathname.indexOf("/api/v3") !== -1) {
|
||||
url.pathname = url.pathname.substring(0, url.pathname.indexOf("/api/v3"));
|
||||
}
|
||||
// Also consider subdomain isolation on GHES
|
||||
if (url.hostname.startsWith("api.")) {
|
||||
url.hostname = url.hostname.substring(4);
|
||||
}
|
||||
// Normalise path to having a trailing slash for consistency
|
||||
if (!url.pathname.endsWith("/")) {
|
||||
url.pathname = `${url.pathname}/`;
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
exports.parseGitHubUrl = parseGitHubUrl;
|
||||
const GITHUB_ENTERPRISE_VERSION_HEADER = "x-github-enterprise-version";
|
||||
const CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR = "CODEQL_ACTION_WARNED_ABOUT_VERSION";
|
||||
let hasBeenWarnedAboutVersion = false;
|
||||
var GitHubVariant;
|
||||
(function (GitHubVariant) {
|
||||
GitHubVariant[GitHubVariant["DOTCOM"] = 0] = "DOTCOM";
|
||||
GitHubVariant[GitHubVariant["GHES"] = 1] = "GHES";
|
||||
GitHubVariant[GitHubVariant["GHAE"] = 2] = "GHAE";
|
||||
})(GitHubVariant = exports.GitHubVariant || (exports.GitHubVariant = {}));
|
||||
async function getGitHubVersion(apiDetails) {
|
||||
// We can avoid making an API request in the standard dotcom case
|
||||
if (parseGitHubUrl(apiDetails.url) === exports.GITHUB_DOTCOM_URL) {
|
||||
return { type: GitHubVariant.DOTCOM };
|
||||
}
|
||||
// Doesn't strictly have to be the meta endpoint as we're only
|
||||
// using the response headers which are available on every request.
|
||||
const apiClient = api_client_1.getApiClient(apiDetails);
|
||||
const response = await apiClient.meta.get();
|
||||
// This happens on dotcom, although we expect to have already returned in that
|
||||
// case. This can also serve as a fallback in cases we haven't foreseen.
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === undefined) {
|
||||
return { type: GitHubVariant.DOTCOM };
|
||||
}
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === "GitHub AE") {
|
||||
return { type: GitHubVariant.GHAE };
|
||||
}
|
||||
const version = response.headers[GITHUB_ENTERPRISE_VERSION_HEADER];
|
||||
return { type: GitHubVariant.GHES, version };
|
||||
}
|
||||
exports.getGitHubVersion = getGitHubVersion;
|
||||
function checkGitHubVersionInRange(version, logger, toolName) {
|
||||
if (hasBeenWarnedAboutVersion || version.type !== GitHubVariant.GHES) {
|
||||
return;
|
||||
}
|
||||
const disallowedAPIVersionReason = apiVersionInRange(version.version, apiCompatibility.minimumVersion, apiCompatibility.maximumVersion);
|
||||
if (disallowedAPIVersionReason === DisallowedAPIVersionReason.ACTION_TOO_OLD) {
|
||||
logger.warning(`The CodeQL ${toolName} version you are using is too old to be compatible with GitHub Enterprise ${version.version}. If you experience issues, please upgrade to a more recent version of the CodeQL ${toolName}.`);
|
||||
}
|
||||
if (disallowedAPIVersionReason === DisallowedAPIVersionReason.ACTION_TOO_NEW) {
|
||||
logger.warning(`GitHub Enterprise ${version.version} is too old to be compatible with this version of the CodeQL ${toolName}. If you experience issues, please upgrade to a more recent version of GitHub Enterprise or use an older version of the CodeQL ${toolName}.`);
|
||||
}
|
||||
hasBeenWarnedAboutVersion = true;
|
||||
if (isActions()) {
|
||||
core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
|
||||
}
|
||||
}
|
||||
exports.checkGitHubVersionInRange = checkGitHubVersionInRange;
|
||||
var DisallowedAPIVersionReason;
|
||||
(function (DisallowedAPIVersionReason) {
|
||||
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_OLD"] = 0] = "ACTION_TOO_OLD";
|
||||
DisallowedAPIVersionReason[DisallowedAPIVersionReason["ACTION_TOO_NEW"] = 1] = "ACTION_TOO_NEW";
|
||||
})(DisallowedAPIVersionReason = exports.DisallowedAPIVersionReason || (exports.DisallowedAPIVersionReason = {}));
|
||||
function apiVersionInRange(version, minimumVersion, maximumVersion) {
|
||||
if (!semver.satisfies(version, `>=${minimumVersion}`)) {
|
||||
return DisallowedAPIVersionReason.ACTION_TOO_NEW;
|
||||
}
|
||||
if (!semver.satisfies(version, `<=${maximumVersion}`)) {
|
||||
return DisallowedAPIVersionReason.ACTION_TOO_OLD;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.apiVersionInRange = apiVersionInRange;
|
||||
/**
|
||||
* Retrieves the github auth token for use with the runner. There are
|
||||
* three possible locations for the token:
|
||||
*
|
||||
* 1. from the cli (considered insecure)
|
||||
* 2. from stdin
|
||||
* 3. from the GITHUB_TOKEN environment variable
|
||||
*
|
||||
* If both 1 & 2 are specified, then an error is thrown.
|
||||
* If 1 & 3 or 2 & 3 are specified, then the environment variable is ignored.
|
||||
*
|
||||
* @param githubAuth a github app token or PAT
|
||||
* @param fromStdIn read the github app token or PAT from stdin up to, but excluding the first whitespace
|
||||
* @param readable the readable stream to use for getting the token (defaults to stdin)
|
||||
*
|
||||
* @return a promise resolving to the auth token.
|
||||
*/
|
||||
async function getGitHubAuth(logger, githubAuth, fromStdIn, readable = process.stdin) {
|
||||
if (githubAuth && fromStdIn) {
|
||||
throw new Error("Cannot specify both `--github-auth` and `--github-auth-stdin`. Please use `--github-auth-stdin`, which is more secure.");
|
||||
}
|
||||
if (githubAuth) {
|
||||
logger.warning("Using `--github-auth` via the CLI is insecure. Use `--github-auth-stdin` instead.");
|
||||
return githubAuth;
|
||||
}
|
||||
if (fromStdIn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let token = "";
|
||||
readable.on("data", (data) => {
|
||||
token += data.toString("utf8");
|
||||
});
|
||||
readable.on("end", () => {
|
||||
token = token.split(/\s+/)[0].trim();
|
||||
if (token) {
|
||||
resolve(token);
|
||||
}
|
||||
else {
|
||||
reject(new Error("Standard input is empty"));
|
||||
}
|
||||
});
|
||||
readable.on("error", (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
return process.env.GITHUB_TOKEN;
|
||||
}
|
||||
throw new Error("No GitHub authentication token was specified. Please provide a token via the GITHUB_TOKEN environment variable, or by adding the `--github-auth-stdin` flag and passing the token via standard input.");
|
||||
}
|
||||
exports.getGitHubAuth = getGitHubAuth;
|
||||
/**
|
||||
* This error is used to indicate a runtime failure of an exhaustivity check enforced at compile time.
|
||||
*/
|
||||
class ExhaustivityCheckingError extends Error {
|
||||
constructor(expectedExhaustiveValue) {
|
||||
super("Internal error: exhaustivity checking failure");
|
||||
this.expectedExhaustiveValue = expectedExhaustiveValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Used to perform compile-time exhaustivity checking on a value. This function will not be executed at runtime unless
|
||||
* the type system has been subverted.
|
||||
*/
|
||||
function assertNever(value) {
|
||||
throw new ExhaustivityCheckingError(value);
|
||||
}
|
||||
exports.assertNever = assertNever;
|
||||
var Mode;
|
||||
(function (Mode) {
|
||||
Mode["actions"] = "Action";
|
||||
Mode["runner"] = "Runner";
|
||||
})(Mode = exports.Mode || (exports.Mode = {}));
|
||||
/**
|
||||
* Environment variables to be set by codeql-action and used by the
|
||||
* CLI. These environment variables are relevant for both the runner
|
||||
* and the action.
|
||||
*/
|
||||
var EnvVar;
|
||||
(function (EnvVar) {
|
||||
/**
|
||||
* The mode of the codeql-action, either 'actions' or 'runner'.
|
||||
*/
|
||||
EnvVar["RUN_MODE"] = "CODEQL_ACTION_RUN_MODE";
|
||||
/**
|
||||
* Semver of the codeql-action as specified in package.json.
|
||||
*/
|
||||
EnvVar["VERSION"] = "CODEQL_ACTION_VERSION";
|
||||
/**
|
||||
* If set to a truthy value, then the codeql-action might combine SARIF
|
||||
* output from several `interpret-results` runs for the same Language.
|
||||
*/
|
||||
EnvVar["FEATURE_SARIF_COMBINE"] = "CODEQL_ACTION_FEATURE_SARIF_COMBINE";
|
||||
/**
|
||||
* If set to the "true" string, then the codeql-action will upload SARIF,
|
||||
* not the cli.
|
||||
*/
|
||||
EnvVar["FEATURE_WILL_UPLOAD"] = "CODEQL_ACTION_FEATURE_WILL_UPLOAD";
|
||||
/**
|
||||
* If set to the "true" string, then the codeql-action is using its
|
||||
* own deprecated and non-standard way of scanning for multiple
|
||||
* languages.
|
||||
*/
|
||||
EnvVar["FEATURE_MULTI_LANGUAGE"] = "CODEQL_ACTION_FEATURE_MULTI_LANGUAGE";
|
||||
/**
|
||||
* If set to the "true" string, then the codeql-action is using its
|
||||
* own sandwiched workflow mechanism
|
||||
*/
|
||||
EnvVar["FEATURE_SANDWICH"] = "CODEQL_ACTION_FEATURE_SANDWICH";
|
||||
})(EnvVar || (EnvVar = {}));
|
||||
function initializeEnvironment(mode, version) {
|
||||
const exportVar = (name, value) => {
|
||||
if (mode === Mode.actions) {
|
||||
core.exportVariable(name, value);
|
||||
}
|
||||
else {
|
||||
process.env[name] = value;
|
||||
}
|
||||
};
|
||||
exportVar(EnvVar.RUN_MODE, mode);
|
||||
exportVar(EnvVar.VERSION, version);
|
||||
exportVar(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
exportVar(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
exportVar(EnvVar.FEATURE_MULTI_LANGUAGE, "true");
|
||||
exportVar(EnvVar.FEATURE_SANDWICH, "true");
|
||||
}
|
||||
exports.initializeEnvironment = initializeEnvironment;
|
||||
function getMode() {
|
||||
// Make sure we fail fast if the env var is missing. This should
|
||||
// only happen if there is a bug in our code and we neglected
|
||||
// to set the mode early in the process.
|
||||
const mode = getRequiredEnvParam(EnvVar.RUN_MODE);
|
||||
if (mode !== Mode.actions && mode !== Mode.runner) {
|
||||
throw new Error(`Unknown mode: ${mode}.`);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
exports.getMode = getMode;
|
||||
function isActions() {
|
||||
return getMode() === Mode.actions;
|
||||
}
|
||||
exports.isActions = isActions;
|
||||
/**
|
||||
* Get an environment parameter, but throw an error if it is not set.
|
||||
*/
|
||||
function getRequiredEnvParam(paramName) {
|
||||
const value = process.env[paramName];
|
||||
if (value === undefined || value.length === 0) {
|
||||
throw new Error(`${paramName} environment variable must be set`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
exports.getRequiredEnvParam = getRequiredEnvParam;
|
||||
class HTTPError extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
exports.HTTPError = HTTPError;
|
||||
function isHTTPError(arg) {
|
||||
var _a;
|
||||
return ((_a = arg) === null || _a === void 0 ? void 0 : _a.status) !== undefined && Number.isInteger(arg.status);
|
||||
}
|
||||
exports.isHTTPError = isHTTPError;
|
||||
//# sourceMappingURL=util.js.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user