Merge pull request #2147 from github/henrymercer/fix-config-outside-workspace-error
Fix an error when loading a configuration specified by the `config` input
This commit is contained in:
commit
3a7796d6ad
6 changed files with 158 additions and 23 deletions
92
.github/workflows/__config-input.yml
generated
vendored
Normal file
92
.github/workflows/__config-input.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
# Warning: This file is generated automatically, and should not be modified.
|
||||||
|
# Instead, please modify the template in the pr-checks directory and run:
|
||||||
|
# (cd pr-checks; pip install ruamel.yaml@0.17.31 && python3 sync.py)
|
||||||
|
# to regenerate this file.
|
||||||
|
|
||||||
|
name: PR Check - Config input
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GO111MODULE: auto
|
||||||
|
CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN: 'true'
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/v*
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- ready_for_review
|
||||||
|
workflow_dispatch: {}
|
||||||
|
jobs:
|
||||||
|
config-input:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: latest
|
||||||
|
name: Config input
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
timeout-minutes: 45
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Setup Python on MacOS
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
if: >-
|
||||||
|
matrix.os == 'macos-latest' && (
|
||||||
|
|
||||||
|
matrix.version == 'stable-20221211' ||
|
||||||
|
|
||||||
|
matrix.version == 'stable-20230418' ||
|
||||||
|
|
||||||
|
matrix.version == 'stable-v2.13.5' ||
|
||||||
|
|
||||||
|
matrix.version == 'stable-v2.14.6')
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Prepare test
|
||||||
|
id: prepare-test
|
||||||
|
uses: ./.github/actions/prepare-test
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.version }}
|
||||||
|
use-all-platform-bundle: 'false'
|
||||||
|
- name: Set environment variable for Swift enablement
|
||||||
|
if: runner.os != 'Windows' && matrix.version == '20221211'
|
||||||
|
shell: bash
|
||||||
|
run: echo "CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT=true" >> $GITHUB_ENV
|
||||||
|
- name: Copy queries into workspace
|
||||||
|
run: |
|
||||||
|
cp -a ../action/queries .
|
||||||
|
|
||||||
|
- uses: ./../action/init
|
||||||
|
with:
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
languages: javascript
|
||||||
|
build-mode: none
|
||||||
|
config: |
|
||||||
|
disable-default-queries: true
|
||||||
|
queries:
|
||||||
|
- name: Run custom query
|
||||||
|
uses: ./queries/default-setup-environment-variables.ql
|
||||||
|
paths-ignore:
|
||||||
|
- tests
|
||||||
|
- lib
|
||||||
|
|
||||||
|
- uses: ./../action/analyze
|
||||||
|
with:
|
||||||
|
output: ${{ runner.temp }}/results
|
||||||
|
|
||||||
|
- name: Check SARIF
|
||||||
|
uses: ./../action/.github/actions/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/codeql-action/default-setup-env-vars
|
||||||
|
queries-not-run: javascript/codeql-action/default-setup-context-properties
|
||||||
|
env:
|
||||||
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|
@ -6,7 +6,7 @@ Note that the only difference between `v2` and `v3` of the CodeQL Action is the
|
||||||
|
|
||||||
## [UNRELEASED]
|
## [UNRELEASED]
|
||||||
|
|
||||||
No user facing changes.
|
- Fix an issue where the CodeQL Action would fail to load a configuration specified by the `config` input to the `init` Action. [#2147](https://github.com/github/codeql-action/pull/2147)
|
||||||
|
|
||||||
## 3.24.2 - 15 Feb 2024
|
## 3.24.2 - 15 Feb 2024
|
||||||
|
|
||||||
|
|
|
||||||
23
lib/config-utils.js
generated
23
lib/config-utils.js
generated
|
|
@ -257,9 +257,15 @@ async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logg
|
||||||
async function loadConfig({ languagesInput, queriesInput, packsInput, buildModeInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, workspacePath, githubVersion, apiDetails, features, logger, }) {
|
async function loadConfig({ languagesInput, queriesInput, packsInput, buildModeInput, configFile, dbLocation, trapCachingEnabled, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, codeql, workspacePath, githubVersion, apiDetails, features, logger, }) {
|
||||||
let parsedYAML;
|
let parsedYAML;
|
||||||
if (isLocal(configFile)) {
|
if (isLocal(configFile)) {
|
||||||
// Treat the config file as relative to the workspace
|
if (configFile !== userConfigFromActionPath(tempDir)) {
|
||||||
configFile = path.resolve(workspacePath, configFile);
|
// If the config file is not generated by the Action, it should be relative to the workspace.
|
||||||
parsedYAML = getLocalConfig(configFile, workspacePath);
|
configFile = path.resolve(workspacePath, configFile);
|
||||||
|
// Error if the config file is now outside of the workspace
|
||||||
|
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||||
|
throw new util_1.ConfigurationError(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsedYAML = getLocalConfig(configFile);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parsedYAML = await getRemoteConfig(configFile, apiDetails);
|
parsedYAML = await getRemoteConfig(configFile, apiDetails);
|
||||||
|
|
@ -457,6 +463,9 @@ function shouldCombine(inputValue) {
|
||||||
function dbLocationOrDefault(dbLocation, tempDir) {
|
function dbLocationOrDefault(dbLocation, tempDir) {
|
||||||
return dbLocation || path.resolve(tempDir, "codeql_databases");
|
return dbLocation || path.resolve(tempDir, "codeql_databases");
|
||||||
}
|
}
|
||||||
|
function userConfigFromActionPath(tempDir) {
|
||||||
|
return path.resolve(tempDir, "user-config-from-action.yml");
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Load and return the config.
|
* Load and return the config.
|
||||||
*
|
*
|
||||||
|
|
@ -471,7 +480,7 @@ async function initConfig(inputs) {
|
||||||
if (inputs.configFile) {
|
if (inputs.configFile) {
|
||||||
logger.warning(`Both a config file and config input were provided. Ignoring config file.`);
|
logger.warning(`Both a config file and config input were provided. Ignoring config file.`);
|
||||||
}
|
}
|
||||||
inputs.configFile = path.resolve(tempDir, "user-config-from-action.yml");
|
inputs.configFile = userConfigFromActionPath(tempDir);
|
||||||
fs.writeFileSync(inputs.configFile, inputs.configInput);
|
fs.writeFileSync(inputs.configFile, inputs.configInput);
|
||||||
logger.debug(`Using config from action input: ${inputs.configFile}`);
|
logger.debug(`Using config from action input: ${inputs.configFile}`);
|
||||||
}
|
}
|
||||||
|
|
@ -506,11 +515,7 @@ function isLocal(configPath) {
|
||||||
}
|
}
|
||||||
return configPath.indexOf("@") === -1;
|
return configPath.indexOf("@") === -1;
|
||||||
}
|
}
|
||||||
function getLocalConfig(configFile, workspacePath) {
|
function getLocalConfig(configFile) {
|
||||||
// Error if the config file is now outside of the workspace
|
|
||||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
|
||||||
throw new util_1.ConfigurationError(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
|
||||||
}
|
|
||||||
// Error if the file does not exist
|
// Error if the file does not exist
|
||||||
if (!fs.existsSync(configFile)) {
|
if (!fs.existsSync(configFile)) {
|
||||||
throw new util_1.ConfigurationError(getConfigFileDoesNotExistErrorMessage(configFile));
|
throw new util_1.ConfigurationError(getConfigFileDoesNotExistErrorMessage(configFile));
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
33
pr-checks/checks/config-input.yml
Normal file
33
pr-checks/checks/config-input.yml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
name: "Config input"
|
||||||
|
description: "Tests specifying configuration using the config input"
|
||||||
|
operatingSystems: ["ubuntu"]
|
||||||
|
versions: ["latest"]
|
||||||
|
steps:
|
||||||
|
- name: Copy queries into workspace
|
||||||
|
run: |
|
||||||
|
cp -a ../action/queries .
|
||||||
|
|
||||||
|
- uses: ./../action/init
|
||||||
|
with:
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
languages: javascript
|
||||||
|
build-mode: none
|
||||||
|
config: |
|
||||||
|
disable-default-queries: true
|
||||||
|
queries:
|
||||||
|
- name: Run custom query
|
||||||
|
uses: ./queries/default-setup-environment-variables.ql
|
||||||
|
paths-ignore:
|
||||||
|
- tests
|
||||||
|
- lib
|
||||||
|
|
||||||
|
- uses: ./../action/analyze
|
||||||
|
with:
|
||||||
|
output: ${{ runner.temp }}/results
|
||||||
|
|
||||||
|
- name: Check SARIF
|
||||||
|
uses: ./../action/.github/actions/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/codeql-action/default-setup-env-vars
|
||||||
|
queries-not-run: javascript/codeql-action/default-setup-context-properties
|
||||||
|
|
@ -543,9 +543,17 @@ async function loadConfig({
|
||||||
let parsedYAML: UserConfig;
|
let parsedYAML: UserConfig;
|
||||||
|
|
||||||
if (isLocal(configFile)) {
|
if (isLocal(configFile)) {
|
||||||
// Treat the config file as relative to the workspace
|
if (configFile !== userConfigFromActionPath(tempDir)) {
|
||||||
configFile = path.resolve(workspacePath, configFile);
|
// If the config file is not generated by the Action, it should be relative to the workspace.
|
||||||
parsedYAML = getLocalConfig(configFile, workspacePath);
|
configFile = path.resolve(workspacePath, configFile);
|
||||||
|
// Error if the config file is now outside of the workspace
|
||||||
|
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||||
|
throw new ConfigurationError(
|
||||||
|
getConfigFileOutsideWorkspaceErrorMessage(configFile),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsedYAML = getLocalConfig(configFile);
|
||||||
} else {
|
} else {
|
||||||
parsedYAML = await getRemoteConfig(configFile, apiDetails);
|
parsedYAML = await getRemoteConfig(configFile, apiDetails);
|
||||||
}
|
}
|
||||||
|
|
@ -823,6 +831,10 @@ function dbLocationOrDefault(
|
||||||
return dbLocation || path.resolve(tempDir, "codeql_databases");
|
return dbLocation || path.resolve(tempDir, "codeql_databases");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function userConfigFromActionPath(tempDir: string): string {
|
||||||
|
return path.resolve(tempDir, "user-config-from-action.yml");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load and return the config.
|
* Load and return the config.
|
||||||
*
|
*
|
||||||
|
|
@ -841,7 +853,7 @@ export async function initConfig(inputs: InitConfigInputs): Promise<Config> {
|
||||||
`Both a config file and config input were provided. Ignoring config file.`,
|
`Both a config file and config input were provided. Ignoring config file.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
inputs.configFile = path.resolve(tempDir, "user-config-from-action.yml");
|
inputs.configFile = userConfigFromActionPath(tempDir);
|
||||||
fs.writeFileSync(inputs.configFile, inputs.configInput);
|
fs.writeFileSync(inputs.configFile, inputs.configInput);
|
||||||
logger.debug(`Using config from action input: ${inputs.configFile}`);
|
logger.debug(`Using config from action input: ${inputs.configFile}`);
|
||||||
}
|
}
|
||||||
|
|
@ -883,14 +895,7 @@ function isLocal(configPath: string): boolean {
|
||||||
return configPath.indexOf("@") === -1;
|
return configPath.indexOf("@") === -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
|
function getLocalConfig(configFile: string): UserConfig {
|
||||||
// Error if the config file is now outside of the workspace
|
|
||||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
|
||||||
throw new ConfigurationError(
|
|
||||||
getConfigFileOutsideWorkspaceErrorMessage(configFile),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error if the file does not exist
|
// Error if the file does not exist
|
||||||
if (!fs.existsSync(configFile)) {
|
if (!fs.existsSync(configFile)) {
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue