diff --git a/README.md b/README.md index c2c90da..29fc4b5 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ For example workflow runs, check out our | licenses.copyleft.exclude | List of Copyleft licenses to remove from default list. Provide licenses as a comma-separated list. | Optional | - | | licenses.copyleft.explicit | Explicit list of Copyleft licenses to consider. Provide licenses as a comma-separated list. | Optional | - | | runtimeContainer | Runtime URL | Optional | `ghcr.io/scanoss/scanoss-py:v1.15.0` | -| skipSnippets | Skip the generation of snippets. (scan_files option must be enabled) | Optional | `false` | +| skipSnippets | Skip the generation of snippets. (scanFiles option must be enabled) | Optional | `false` | | scanFiles | Enable or disable file and snippet scanning | Optional | `true` | | scanossSettings | Settings file to use for scanning. See the SCANOSS settings [documentation](https://scanoss.readthedocs.io/projects/scanoss-py/en/latest/#settings-file) | Optional | `true` | | settingsFilepath | Filepath of the SCANOSS settings to be used for scanning | Optional | `scanoss.json` | diff --git a/__tests__/data/test-results.json b/__tests__/data/test-results.json deleted file mode 100644 index 0967ef4..0000000 --- a/__tests__/data/test-results.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/__tests__/undeclared-policy-check.test.ts b/__tests__/undeclared-policy-check.test.ts index 1294784..03c69a3 100644 --- a/__tests__/undeclared-policy-check.test.ts +++ b/__tests__/undeclared-policy-check.test.ts @@ -37,7 +37,7 @@ describe('UndeclaredPolicyCheck', () => { scannerResults = JSON.parse(resultsMock[3].content); undeclaredPolicyCheck = new UndeclaredPolicyCheck(); - }); + }, 30000); it('should pass the policy check when undeclared components are not found', async () => { const TEST_DIR = __dirname; @@ -50,7 +50,7 @@ describe('UndeclaredPolicyCheck', () => { await undeclaredPolicyCheck.run(); expect(undeclaredPolicyCheck.conclusion).toEqual(CONCLUSION.Success); - }); + }, 30000); it('should fail the policy check when undeclared components are found', async () => { const TEST_DIR = __dirname; @@ -63,5 +63,5 @@ describe('UndeclaredPolicyCheck', () => { await undeclaredPolicyCheck.run(); expect(undeclaredPolicyCheck.conclusion).toEqual(CONCLUSION.Neutral); - }); + }, 30000); }); diff --git a/dist/index.js b/dist/index.js index 08b0593..2e99910 100644 --- a/dist/index.js +++ b/dist/index.js @@ -125946,7 +125946,43 @@ exports.run = run; /***/ }), -/***/ 34466: +/***/ 26658: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +// SPDX-License-Identifier: MIT +/* + Copyright (c) 2024, SCANOSS + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.ArgumentBuilder = void 0; +class ArgumentBuilder { +} +exports.ArgumentBuilder = ArgumentBuilder; + + +/***/ }), + +/***/ 84156: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -125997,22 +126033,11 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CopyleftPolicyCheck = void 0; -const core = __importStar(__nccwpck_require__(42186)); -const app_config_1 = __nccwpck_require__(29014); -const policy_check_1 = __nccwpck_require__(63702); +exports.CopyLeftArgumentBuilder = void 0; +const argument_builder_1 = __nccwpck_require__(26658); const app_input_1 = __nccwpck_require__(483); -const exec = __importStar(__nccwpck_require__(71514)); -/** - * This class checks if any of the components identified in the scanner results are subject to copyleft licenses. - * It filters components based on their licenses and looks for those with copyleft obligations. - * It then generates a summary and detailed report of the findings. - */ -class CopyleftPolicyCheck extends policy_check_1.PolicyCheck { - static policyName = 'Copyleft Policy'; - constructor() { - super(`${app_config_1.CHECK_NAME}: ${CopyleftPolicyCheck.policyName}`); - } +const core = __importStar(__nccwpck_require__(42186)); +class CopyLeftArgumentBuilder extends argument_builder_1.ArgumentBuilder { buildCopyleftArgs() { if (app_input_1.COPYLEFT_LICENSE_EXPLICIT) { core.info(`Explicit copyleft licenses: ${app_input_1.COPYLEFT_LICENSE_EXPLICIT}`); @@ -126028,7 +126053,7 @@ class CopyleftPolicyCheck extends policy_check_1.PolicyCheck { } return []; } - buildArgs() { + async build() { return [ 'run', '-v', @@ -126043,10 +126068,139 @@ class CopyleftPolicyCheck extends policy_check_1.PolicyCheck { ...this.buildCopyleftArgs() ]; } +} +exports.CopyLeftArgumentBuilder = CopyLeftArgumentBuilder; + + +/***/ }), + +/***/ 48628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +// SPDX-License-Identifier: MIT +/* + Copyright (c) 2024, SCANOSS + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.UndeclaredArgumentBuilder = void 0; +const argument_builder_1 = __nccwpck_require__(26658); +const app_input_1 = __nccwpck_require__(483); +class UndeclaredArgumentBuilder extends argument_builder_1.ArgumentBuilder { + async build() { + return [ + 'run', + '-v', + `${app_input_1.REPO_DIR}:/scanoss`, + app_input_1.RUNTIME_CONTAINER, + 'inspect', + 'undeclared', + '--input', + app_input_1.OUTPUT_FILEPATH, + '--format', + 'md', + ...(!app_input_1.SCANOSS_SETTINGS ? ['--sbom-format', 'legacy'] : []) // Sets sbom format output to legacy if SCANOSS_SETTINGS is not true + ]; + } +} +exports.UndeclaredArgumentBuilder = UndeclaredArgumentBuilder; + + +/***/ }), + +/***/ 34466: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +// SPDX-License-Identifier: MIT +/* + Copyright (c) 2024, SCANOSS + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.CopyleftPolicyCheck = void 0; +const core = __importStar(__nccwpck_require__(42186)); +const app_config_1 = __nccwpck_require__(29014); +const policy_check_1 = __nccwpck_require__(63702); +const app_input_1 = __nccwpck_require__(483); +const exec = __importStar(__nccwpck_require__(71514)); +const copyleft_argument_builder_1 = __nccwpck_require__(84156); +/** + * This class checks if any of the components identified in the scanner results are subject to copyleft licenses. + * It filters components based on their licenses and looks for those with copyleft obligations. + * It then generates a summary and detailed report of the findings. + */ +class CopyleftPolicyCheck extends policy_check_1.PolicyCheck { + static policyName = 'Copyleft Policy'; + argumentBuilder; + constructor(argumentBuilder = new copyleft_argument_builder_1.CopyLeftArgumentBuilder()) { + super(`${app_config_1.CHECK_NAME}: ${CopyleftPolicyCheck.policyName}`); + this.argumentBuilder = argumentBuilder; + } async run() { core.info(`Running Copyleft Policy Check...`); super.initStatus(); - const args = this.buildArgs(); + const args = await this.argumentBuilder.build(); const options = { failOnStdErr: false, ignoreReturnCode: true @@ -126402,6 +126556,7 @@ const app_config_1 = __nccwpck_require__(29014); const core = __importStar(__nccwpck_require__(42186)); const app_input_1 = __nccwpck_require__(483); const exec = __importStar(__nccwpck_require__(71514)); +const undeclared_argument_builder_1 = __nccwpck_require__(48628); /** * Verifies that all components identified in scanner results are declared in the project's SBOM. * The run method compares components found by the scanner against those declared in the SBOM. @@ -126411,28 +126566,15 @@ const exec = __importStar(__nccwpck_require__(71514)); */ class UndeclaredPolicyCheck extends policy_check_1.PolicyCheck { static policyName = 'Undeclared Policy'; - constructor() { + argumentBuilder; + constructor(argumentBuilder = new undeclared_argument_builder_1.UndeclaredArgumentBuilder()) { super(`${app_config_1.CHECK_NAME}: ${UndeclaredPolicyCheck.policyName}`); - } - buildArgs() { - return [ - 'run', - '-v', - `${app_input_1.REPO_DIR}:/scanoss`, - app_input_1.RUNTIME_CONTAINER, - 'inspect', - 'undeclared', - '--input', - app_input_1.OUTPUT_FILEPATH, - '--format', - 'md', - ...(!app_input_1.SCANOSS_SETTINGS ? ['--sbom-format', 'legacy'] : []) // Sets sbom format output to legacy if SCANOSS_SETTINGS is not true - ]; + this.argumentBuilder = argumentBuilder; } async run() { core.info(`Running Undeclared Components Policy Check...`); super.initStatus(); - const args = this.buildArgs(); + const args = await this.argumentBuilder.build(); core.debug(`Args: ${args}`); const options = { failOnStdErr: false, @@ -127073,6 +127215,7 @@ class ScanService { async detectSBOM() { // Overrides sbom file if is set if (this.options.scanossSettings) { + core.debug(`[SCANOSS SETTINGS ENABLED] ${this.options.sbomFilepath}, ${this.options.sbomFilepath}`); try { await fs_1.default.promises.access(this.options.settingsFilePath, fs_1.default.constants.F_OK); return ['--settings', this.options.settingsFilePath]; @@ -127087,8 +127230,10 @@ class ScanService { } if (!this.options.sbomEnabled || !this.options.sbomFilepath) return []; + core.debug(`[SBOM ENABLED] ${this.options.sbomFilepath}, ${this.options.sbomFilepath}`); try { await fs_1.default.promises.access(this.options.sbomFilepath, fs_1.default.constants.F_OK); + core.debug(`[SBOM ENABLED] - Adding sbom to scan parameters`); return [`--${this.options.sbomType?.toLowerCase()}`, this.options.sbomFilepath]; } catch (error) { diff --git a/policy-check-undeclared-results.md b/policy-check-undeclared-results.md new file mode 100644 index 0000000..6d70fcd --- /dev/null +++ b/policy-check-undeclared-results.md @@ -0,0 +1,25 @@ +5 undeclared component(s) were found. +Add the following snippet into your `sbom.json` file + +```json +{ + "components": [ + { + "purl": "pkg:github/scanoss/wfp" + }, + { + "purl": "pkg:github/scanoss/scanner.c" + }, + { + "purl": "pkg:npm/%40grpc/grpc-js" + }, + { + "purl": "pkg:npm/abort-controller" + }, + { + "purl": "pkg:npm/adm-zip" + } + ] +} +``` + diff --git a/src/services/scan.service.ts b/src/services/scan.service.ts index d7fdabf..22b5f45 100644 --- a/src/services/scan.service.ts +++ b/src/services/scan.service.ts @@ -346,6 +346,7 @@ export class ScanService { private async detectSBOM(): Promise { // Overrides sbom file if is set if (this.options.scanossSettings) { + core.debug(`[SCANOSS SETTINGS ENABLED] ${this.options.sbomFilepath}, ${this.options.sbomFilepath}`); try { await fs.promises.access(this.options.settingsFilePath, fs.constants.F_OK); return ['--settings', this.options.settingsFilePath]; @@ -358,9 +359,10 @@ export class ScanService { } if (!this.options.sbomEnabled || !this.options.sbomFilepath) return []; - + core.debug(`[SBOM ENABLED] ${this.options.sbomFilepath}, ${this.options.sbomFilepath}`); try { await fs.promises.access(this.options.sbomFilepath, fs.constants.F_OK); + core.debug(`[SBOM ENABLED] - Adding sbom to scan parameters`); return [`--${this.options.sbomType?.toLowerCase()}`, this.options.sbomFilepath]; } catch (error: any) { core.error(error.message);