diff --git a/.github/workflows/build-sdk-js.yml b/.github/workflows/build-sdk-js.yml index d0c8d0be..65360566 100644 --- a/.github/workflows/build-sdk-js.yml +++ b/.github/workflows/build-sdk-js.yml @@ -25,7 +25,7 @@ jobs: path: ${{github.workspace}}/sdk - uses: ./code-build-actions/build-js-sdk with: - dry-run: true + dry-run: 'true' app_directory: ${{ github.workspace }} sdk_output_directory: ${{github.workspace}}/sdk token: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/lua-lint.yml b/.github/workflows/lua-lint.yml new file mode 100644 index 00000000..ae612487 --- /dev/null +++ b/.github/workflows/lua-lint.yml @@ -0,0 +1,28 @@ +name: Luacheck Test + +on: + pull_request: + branches: + - main + push: + branches: + - main + tags: + - '*' + workflow_dispatch: {} + +jobs: + test-lua-lint: + env: + TEST_REPOSITORY: "${{github.repository_owner}}/atc-router" + runs-on: ubuntu-latest + name: Luacheck code analysis + steps: + - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + with: + repository: ${{env.TEST_REPOSITORY}} + path: ${{env.TEST_REPOSITORY}} + - uses: ./code-check-actions/lua-lint + with: + additional_args: '--no-default-config --config ${{env.TEST_REPOSITORY}}/.luacheckrc ${{env.TEST_REPOSITORY}}' diff --git a/.github/workflows/luacheck.yml b/.github/workflows/luacheck.yml deleted file mode 100644 index 5f82407e..00000000 --- a/.github/workflows/luacheck.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Luacheck Test - -on: - pull_request: - branches: - - main - push: - branches: - - main - tags: - - '*' - workflow_dispatch: {} - -jobs: - test-luacheck: - env: - LUA_TEST_REPOSITORY: "Kong/lua-resty-lmdb" - runs-on: ubuntu-latest - name: Test Lua code analysis check - steps: - - uses: actions/checkout@v3 - - uses: actions/checkout@v3 - with: - repository: ${{env.LUA_TEST_REPOSITORY}} - path: ${{env.LUA_TEST_REPOSITORY}} - - uses: ./code-check-actions/luacheck - with: - args: '--no-default-config --config ${{env.LUA_TEST_REPOSITORY}}/.luacheckrc ${{env.LUA_TEST_REPOSITORY}}' diff --git a/.github/workflows/rust-lint.yml b/.github/workflows/rust-lint.yml new file mode 100644 index 00000000..00755282 --- /dev/null +++ b/.github/workflows/rust-lint.yml @@ -0,0 +1,37 @@ +name: Rust Lint Test + +on: + pull_request: + branches: + - main + push: + branches: + - main + tags: + - '*' + workflow_dispatch: {} + +jobs: + test-rust-lint: + permissions: + # required for all workflows + security-events: write + checks: write + pull-requests: write + # only required for workflows in private repositories + actions: read + contents: read + env: + TEST_REPOSITORY: "${{github.repository_owner}}/atc-router" + runs-on: ubuntu-latest + name: Rust Code Linting checks + steps: + - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + with: + repository: ${{env.TEST_REPOSITORY}} + path: ${{env.TEST_REPOSITORY}} + - uses: ./code-check-actions/rust-lint + with: + token: ${{secrets.GITHUB_TOKEN}} + manifest_dir: ${{ github.workspace }}/${{env.TEST_REPOSITORY}} \ No newline at end of file diff --git a/.github/workflows/rust-sca.yml b/.github/workflows/rust-sca.yml new file mode 100644 index 00000000..ca66fb5f --- /dev/null +++ b/.github/workflows/rust-sca.yml @@ -0,0 +1,38 @@ +name: Rust SCA Test + +on: + pull_request: + branches: + - main + push: + branches: + - main + tags: + - '*' + workflow_dispatch: {} + +jobs: + test-rust-sca: + permissions: + # required for all workflows + security-events: write + checks: write + pull-requests: write + # only required for workflows in private repositories + actions: read + contents: read + env: + TEST_REPOSITORY: "${{github.repository_owner}}/atc-router" + runs-on: ubuntu-latest + name: Rust code analysis and SCA checks + steps: + - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + with: + repository: ${{env.TEST_REPOSITORY}} + path: ${{env.TEST_REPOSITORY}} + - uses: ./security-actions/scan-rust + with: + asset_prefix: ${{env.TEST_REPOSITORY}} + dir: ${{ github.workspace }}/${{env.TEST_REPOSITORY}} + codeql_upload: false \ No newline at end of file diff --git a/.github/workflows/rustcheck.yml b/.github/workflows/rustcheck.yml deleted file mode 100644 index 186d9744..00000000 --- a/.github/workflows/rustcheck.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Rust checks - -on: - pull_request: - branches: - - main - push: - branches: - - main - tags: - - '*' - workflow_dispatch: {} - -jobs: - test-rust-checks: - env: - RUST_TEST_REPOSITORY: "Kong/atc-router" - outputs: - grype-report: ${{ steps.rust_checks.outputs.grype-sarif-report }} - sbom-spdx-report: ${{ steps.rust_checks.outputs.sbom-spdx-report }} - sbom-cyclonedx-report: ${{ steps.rust_checks.outputs.sbom-cyclonedx-report }} - runs-on: ubuntu-latest - name: Rust scan and vulnerability SCA checks - steps: - - uses: actions/checkout@v3 - - uses: actions/checkout@v3 - with: - repository: ${{env.RUST_TEST_REPOSITORY}} - path: ${{env.RUST_TEST_REPOSITORY}} - - uses: ./code-check-actions/rustcheck - with: - asset_prefix: ${{env.RUST_TEST_REPOSITORY}} - dir: ${{ github.workspace }}/${{env.RUST_TEST_REPOSITORY}} - token: ${{secrets.GITHUB_TOKEN}} \ No newline at end of file diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 00000000..38ba402b --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,38 @@ +name: Semgrep + +on: + pull_request: {} + push: + branches: + - master + - main + workflow_dispatch: {} + + +jobs: + semgrep: + name: SAST + runs-on: ubuntu-20.04 + permissions: + # required for all workflows + security-events: write + # only required for workflows in private repositories + actions: read + contents: read + env: + TEST_REPOSITORY: "${{github.repository_owner}}/atc-router" + if: (github.actor != 'dependabot[bot]') + + steps: + - uses: actions/checkout@v3 + - uses: actions/checkout@v3 + with: + repository: ${{env.TEST_REPOSITORY}} + token: ${{secrets.GITHUB_TOKEN}} + path: ${{env.TEST_REPOSITORY}} + - uses: ./security-actions/semgrep + with: + additional_config: '--config p/rust' + codeql_upload: false + fail_on_findings: false + diff --git a/CODEOWNERS b/CODEOWNERS index 175cca76..6ecdfa7a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,5 @@ * @Kong/team-shared-actions-reviewers -security-actions/ @Kong/team-security-engineering \ No newline at end of file +security-actions/ @Kong/team-security-engineering +pr-previews/ @adamdehaven @ValeryG @Drew-Kimberly +code-check-actions/ @Kong/team-security-engineering diff --git a/README.md b/README.md index 5e0684e0..8b8ddab3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # public-shared-actions Shared actions available to both public and private repositories + +## Usage + + ```yaml + - uses: Kong/public-shared-actions/@ + ``` + + For example: + + ```yaml + - uses: Kong/public-shared-actions/code-build-actions/build-js-sdk@v1.6.0 + ``` + + \ No newline at end of file diff --git a/code-build-actions/build-js-sdk/README.md b/code-build-actions/build-js-sdk/README.md index 7a740d42..9a19e0c4 100644 --- a/code-build-actions/build-js-sdk/README.md +++ b/code-build-actions/build-js-sdk/README.md @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Build JS SDK - uses: Kong/public-shared-actions/build-js-sdk@main + uses: Kong/public-shared-actions/code-build-actions/build-js-sdk ``` diff --git a/code-build-actions/build-js-sdk/action.yaml b/code-build-actions/build-js-sdk/action.yaml index 994ec42f..67efedb9 100644 --- a/code-build-actions/build-js-sdk/action.yaml +++ b/code-build-actions/build-js-sdk/action.yaml @@ -5,7 +5,7 @@ inputs: dry-run: description: 'If true, the action will not push the changes to the PR' required: false - default: false + default: 'false' token: description: 'A Github Token' required: true @@ -50,17 +50,9 @@ runs: shell: bash working-directory: ${{inputs.sdk_output_directory}} run: | - openapi-generator-cli generate --generator-key client + openapi-generator-cli generate --generator-key client -o src - name: "Clean up generator files" shell: bash working-directory: ${{inputs.sdk_output_directory}}/src run: | rm -rf openapitools.json templates-js .openapi-generator-ignore .openapi-generator git_push.sh - - name: Commit SDK changes to the PR - uses: EndBug/add-and-commit@v9 - if: ${{ !inputs.dry-run }} - with: - cwd: ${{inputs.sdk_output_directory}} - add: src - default_author: github_actions - message: Update SDK based on openapi.yaml changes diff --git a/code-check-actions/lua-lint/README.md b/code-check-actions/lua-lint/README.md new file mode 100644 index 00000000..eff376c7 --- /dev/null +++ b/code-check-actions/lua-lint/README.md @@ -0,0 +1,71 @@ +# Lua Check - Github Action + +Luacheck is a static analyzer for Lua. The options for static analysis configuration can be used on the command line, put into a config file or directly into checked files as Lua comments. + +This action analyzes all changed lua files using [lunarmodules/luacheck](https://github.com/lunarmodules/luacheck). + +This action looks for any `cli` arguments and a deafult `.luacheckrc` config to derive the final configuaration as mentioned in [docs](https://luacheck.readthedocs.io/en/stable/cli.html#command-line-options) + +## Inputs + +```yaml +additional_args: + description: 'Arguments to luacheck' + required: 'false' + default: '.' # Default: Run luacheck on workspace dir +``` + +## Outputs +- Depending on the event, refer [publishing](https://github.com/EnricoMi/publish-unit-test-result-action#publishing-test-results) + +## Action Output +- Always exit with 0 even when there are warnings / errors and be non-blocking +- The failure mode of build is not configurable based on shared action outcome + +## Example usage + +```yaml +name: Lua Code Quality + +on: + pull_request: {} + workflow_dispatch: {} + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + lua: + name: Lua Lint + runs-on: ubuntu-20.04 + permissions: + contents: read + issues: read + checks: write + pull-requests: write + if: (github.actor != 'dependabot[bot]') + + steps: + - name: Checkout source code + uses: actions/checkout@v3 + + # Optional step to run on only changed files + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v36 + with: + files: | + **.lua + + - name: Lua Check + if: steps.changed-files.outputs.any_changed == 'true' + uses: Kong/public-shared-actions/code-check-actions/luacheck@main + with: + additional_args: '--no-default-config --config .luacheckrc' + files: ${{ steps.changed-files.outputs.all_changed_files }} +``` + diff --git a/code-check-actions/lua-lint/action.yml b/code-check-actions/lua-lint/action.yml new file mode 100644 index 00000000..1f4b0b44 --- /dev/null +++ b/code-check-actions/lua-lint/action.yml @@ -0,0 +1,54 @@ +name: Luacheck +description: Static analysis of Lua +author: 'Kong' +inputs: + additional_args: + description: 'Arguments for Luacheck' + required: false + default: '' # Scans workspace dir + files: + description: 'List of files, directories and rockspecs to check' + required: false + default: '.' # Scans workspace dir + +runs: + using: composite + steps: + + - name: Run Luacheck for static analysis + uses: lunarmodules/luacheck@fcbdeacad00e643e0d78c56b9ba6d8b3c7fa584f + continue-on-error: true + with: + args: "${{ inputs.additional_args }} --codes --ranges --formatter JUnit -q ${{ inputs.files }} > luacheck_${{github.sha}}.xml" + + - name: Upload results to workflow + if: always() + uses: actions/upload-artifact@v3 + with: + name: luacheck_results.zip + path: | + luacheck_${{github.sha}}.xml + if-no-files-found: warn + +# - name: Print Luacheck results +# shell: bash +# run: | +# cat luacheck_${{github.sha}}.xml + + # when using the regular GITHUB_TOKEN, the check-run created by this step will be assigned to a + # random workflow in the GH UI. to prevent this, we can force the check-run to be created in a separate + # check-suite, which is created automatically if we use the credentials of a GitHub App + # Ref: https://github.com/EnricoMi/publish-unit-test-result-action/issues/181 + # Publishing: https://github.com/EnricoMi/publish-unit-test-result-action#publishing-test-results + - name: Luacheck Report + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: | + luacheck_${{github.sha}}.xml + check_name: Luacheck Report + comment_mode: always + action_fail: false + fail_on: 'nothing' # Explicitly don't fail reporting check based on test results + + diff --git a/code-check-actions/luacheck/README.md b/code-check-actions/luacheck/README.md deleted file mode 100644 index 34f996ec..00000000 --- a/code-check-actions/luacheck/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Lua Check - Github Action - -Luacheck is a static analyzer for Lua. The options for static analysis configuration can be used on the command line, put into a config file or directly into checked files as Lua comments. - -This action analyzes all changed lua files using [lunarmodules/luacheck](https://github.com/lunarmodules/luacheck). - -This action looks for any `cli` arguments and a deafult `.luacheckrc` config to derive the final configuaration as mentioned in [docs](https://luacheck.readthedocs.io/en/stable/cli.html#command-line-options) - -## User tracking - -Currently, these repos are using this action: - -[] - -## Inputs - -```yaml -args: - description: 'Arguments to luacheck' - required: 'false' - default: '.' # Default: Run luacheck on workspace dir -``` - -## Action status -The status outcome of the action will depend based on the follwing: - -- Exit code is 0 if no warnings or errors occurred. -- Exit code is 1 if some warnings occurred but there were no syntax errors or invalid inline options. -- Exit code is 2 if there were some syntax errors or invalid inline options. -- Exit code is 3 if some files couldn’t be checked, typically due to an incorrect file name. -- Exit code is 4 if there was a critical error (invalid CLI arguments, config, or cache file). - -## Example usage - -```yaml -uses: Kong/public-shared-actions/code-check-actions/luacheck@main - -``` - -## Detailed example - -```yaml -name: Luacheck - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - luacheck: - runs-on: ubuntu-latest - name: Lua code analysis check - steps: - - uses: actions/checkout@v3 - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@04124efe7560d15e11ea2ba96c0df2989f68f1f4 - with: - base_sha: ${{ github.event.workflow_run.head_sha }} - - uses: Kong/public-shared-actions/code-check-actions/luacheck@main - with: - args: "${{ steps.changed-files.outputs.all_changed_files }}" -``` \ No newline at end of file diff --git a/code-check-actions/luacheck/action.yml b/code-check-actions/luacheck/action.yml deleted file mode 100644 index 5409cbfc..00000000 --- a/code-check-actions/luacheck/action.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Luacheck satic analysis -description: Static analysis of Lua -author: 'Kong' -inputs: - args: - description: 'arguments for Luacheck' - required: false - default: '.' # Scans workspace dir - -runs: - using: composite - steps: - - - name: Run Luacheck for static analysis - uses: lunarmodules/luacheck@fcbdeacad00e643e0d78c56b9ba6d8b3c7fa584f - with: - args: "${{ inputs.args }}" diff --git a/code-check-actions/rust-lint/README.md b/code-check-actions/rust-lint/README.md new file mode 100644 index 00000000..fa2fd4de --- /dev/null +++ b/code-check-actions/rust-lint/README.md @@ -0,0 +1,70 @@ +# Rust clippy - Github Action + +This action uses Rust Clippy for code quality checks + + +The action runs the following: +- Installs rust +- Run `clippy` to identify linting and code quality checks + +## Inputs + +```yaml +manifest_dir: + description: 'Speicify a directory to be scanned' + required: false + default: '.' +``` + +## Outputs: + +- All Clippy Findings are reported as `Warnings` on the github check `Rust Clippy Report` + +- On Push: Commit check summary +- On PR: Github check Summary and PR annotations + +## Action Output +- Report findings as warnings and be non-blocking +- The failure mode of build is not configurable based on shared action outcome + +## Detailed example + +```yaml +name: Rust Code Quality + +on: + pull_request: {} + workflow_dispatch: {} + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + rust: + name: Rust Clippy + runs-on: ubuntu-20.04 + + permissions: + # required for all workflows + security-events: write + checks: write + pull-requests: write + # only required for workflows in private repositories + actions: read + contents: read + + if: (github.actor != 'dependabot[bot]') + + steps: + - name: Checkout source code + uses: actions/checkout@v3 + + - name: Rust Check + uses: Kong/public-shared-actions/code-check-actions/rust-lint@main + with: + token: ${{ secrets.GITHUB_TOKEN }} +``` \ No newline at end of file diff --git a/code-check-actions/rust-lint/action.yml b/code-check-actions/rust-lint/action.yml new file mode 100644 index 00000000..bd1886a9 --- /dev/null +++ b/code-check-actions/rust-lint/action.yml @@ -0,0 +1,71 @@ +name: Rust Clippy +description: Rust Linting using Clippy +author: 'Kong' +inputs: + manifest_dir: + description: 'Rust Manifest Directory' + required: false + default: '.' + token: + description: 'Github token to annotate files with findings' + required: true + +runs: + using: composite + steps: + + - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f + with: + toolchain: stable + components: clippy + + - name: Set Job Metadata + shell: bash + id: meta + env: + manifest_dir: ${{ inputs.manifest_dir }} + run: $GITHUB_ACTION_PATH/scripts/set-env.sh + + - uses: Swatinem/rust-cache@v1 + + - uses: actions-rs/clippy-check@v1 + continue-on-error: true + with: + token: ${{ inputs.token }} + # Explicitly report all findings as warnings to not fail the reporiting status check + args: --manifest-path ${{ steps.meta.outputs.manifest_path }} -- -W clippy::correctness -W clippy::cargo -W clippy::suspicious -W clippy::style + name: Rust Clippy Report + + # - uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b + # continue-on-error: true + # with: + # command: install + # args: "clippy-sarif sarif-fmt" + + # - name: Run Cargo Clippy + # shell: bash + # continue-on-error: true + # run: | + # cargo clippy --manifest-path ${{ steps.meta.outputs.manifest_path }} --message-format=json -- -W clippy::correctness -W clippy::cargo -W clippy::pedantic | clippy-sarif | tee rust_clippy_${{github.sha}}.sarif | sarif-fmt + + # - name: Upload Rust Linting SARIF file to CodeQL + # if: ${{ github.event.repository.visibility == 'public' }} + # uses: github/codeql-action/upload-sarif@v2 + # with: + # sarif_file: rust_clippy_${{github.sha}}.sarif + # category: clippy_rust + + # - name: Upload Rust Linting results to workflow + # if: always() + # uses: actions/upload-artifact@v3 + # with: + # name: rust_clippy_results.sarif + # path: | + # rust_clippy_${{github.sha}}.sarif + # if-no-files-found: warn + + # # Rust Clippy - Linting report + # - name: Rust Linting Report - SARIF + # shell: bash + # run: | + # cat rust_clippy_${{github.sha}}.sarif diff --git a/code-check-actions/rust-lint/scripts/set-env.sh b/code-check-actions/rust-lint/scripts/set-env.sh new file mode 100755 index 00000000..05926c12 --- /dev/null +++ b/code-check-actions/rust-lint/scripts/set-env.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ -n ${manifest_dir} ]]; then + echo "manifest_path=${manifest_dir}/Cargo.toml" >> $GITHUB_OUTPUT +fi \ No newline at end of file diff --git a/code-check-actions/rustcheck/README.md b/code-check-actions/rustcheck/README.md deleted file mode 100644 index e3d4cc5c..00000000 --- a/code-check-actions/rustcheck/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Rust Directory Scan - Github Action - -This action uses syft and grype for SCA. It will only support scanning source code directories / files and will not support the container images - - -The action runs the following: -- Installs rust and tools like clippy and fmt -- Runs `rust fmt` -- Runs `rust check` -- Runs `rust clippy` for all standard lint groups in Warn Mode -- SBOM in spdx and cyclonedx. -- CVE sarif and json - -## User tracking - -Currently, these repos are using this action: - -[] - -## Inputs - -```yaml -args: - description: 'Arguments to luacheck' - required: 'false' - default: '.' # Default: Run luacheck on workspace dir -``` - -## Action status -The status outcome of the action will depend based on the follwing: - -- Exit code is 0 if no warnings or errors occurred. -- Exit code is 1 if some warnings occurred but there were no syntax errors or invalid inline options. -- Exit code is 2 if there were some syntax errors or invalid inline options. -- Exit code is 3 if some files couldn’t be checked, typically due to an incorrect file name. -- Exit code is 4 if there was a critical error (invalid CLI arguments, config, or cache file). - -## Example usage - -```yaml -uses: Kong/public-shared-actions/code-check-actions/rustcheck@main - -``` - -## Detailed example - -```yaml -name: Test Rust Lint and SCA Checks - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - test-rust-checks: - outputs: - grype-report: ${{ steps.rust_checks.outputs.grype-sarif-report }} - sbom-spdx-report: ${{ steps.rust_checks.outputs.sbom-spdx-report }} - sbom-cyclonedx-report: ${{ steps.rust_checks.outputs.sbom-cyclonedx-report }} - runs-on: ubuntu-latest - name: Rust scan and vulnerability SCA checks - steps: - - uses: actions/checkout@v3 - - id: rust_checks - uses: Kong/public-shared-actions/code-check-actions/rustcheck@main - with: - asset_prefix: ${{ env.DOCKER_BASE_IMAGE_NAME }} - dir: ${{ github.workspace }} -``` \ No newline at end of file diff --git a/code-check-actions/rustcheck/action.yml b/code-check-actions/rustcheck/action.yml deleted file mode 100644 index ee58a267..00000000 --- a/code-check-actions/rustcheck/action.yml +++ /dev/null @@ -1,194 +0,0 @@ -name: Rust Source Code Lints -description: Rust linting and SCA using grype on specified rust source code -author: 'Kong' -inputs: - asset_prefix: - description: 'prefix for generated artifacts' - required: false - default: '' - dir: - description: 'Speicify a directory to be checked and scanned' - required: false - default: '.' - fail_build: - description: 'fail the build if the vulnerability is above the severity cutoff' - required: false - default: false - type: choice - options: - - 'true' - - 'false' - token: - description: 'A Github PAT' - required: true - -outputs: - grype-json-report: - description: 'vulnerability json report' - value: ${{ steps.grype_analysis.outputs.json }} - grype-sarif-report: - description: 'vulnerability sarif report' - value: ${{ steps.grype_analysis.outputs.sarif }} - sbom-spdx-report: - description: 'SBOM spdx report' - value: ${{ steps.meta.outputs.sbom_spdx_file }} - sbom-cyclonedx-report: - description: 'SBOM cyclonedx report' - value: ${{ steps.meta.outputs.sbom_cyclonedx_file }} - -runs: - using: composite - steps: - - - uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f - with: - profile: default - toolchain: stable - components: rustfmt, clippy - - - name: Set Scan Job Metadata - shell: bash - id: meta - env: - DIR: ${{ inputs.dir }} - FILE: ${{ inputs.file }} - ASSET_PREFIX: ${{ inputs.asset_prefix }} - run: $GITHUB_ACTION_PATH/scripts/scan-metadata.sh - - # fails with an error code / succeeds - # - uses: actions-rs/cargo@v1 - # continue-on-error: true - # with: - # command: "fmt" - # args: "--all --manifest-path ${{ steps.meta.outputs.lint_path }}" - - # fails with an error code / succeeds - # Run as part of clippy - # - uses: actions-rs/cargo@v1 - # continue-on-error: true - # with: - # command: check - # args: "--manifest-path ${{ steps.meta.outputs.lint_path }}" - - # fail on any correctness lint groups - # always warn other lint groups - - uses: actions-rs/cargo@ae10961054e4aa8b4aa7dffede299aaf087aa33b - continue-on-error: true - with: - command: clippy # Runs all default clippy::all lints for warn mode - args: "--manifest-path ${{ steps.meta.outputs.lint_path }} -- -D clippy::correctness -W clippy::all -W clippy::cargo -W clippy::pedantic" - - # - uses: auguwu/clippy-action@1.1.0 - # with: - # token: ${{ inputs.token }} - # working-directory: ${{ steps.meta.outputs.lint_path }} - # warn: "all,cargo,pedantic" - # deny: "correctness" - # forbid: "restriction,nursery" - - # Must upload artifact for output file parameter to have effect - - name: Generate SPDX SBOM Using Syft - uses: anchore/sbom-action@v0.13.4 - id: sbom_spdx - with: - image: ${{ steps.meta.outputs.scan_image }} - registry-username: ${{ inputs.registry_username }} - registry-password: ${{ inputs.registry_password }} - path: ${{ steps.meta.outputs.scan_dir }} - file: ${{ steps.meta.outputs.scan_file }} - format: spdx-json - artifact-name: ${{ steps.meta.outputs.sbom_spdx_file }} - output-file: ${{ steps.meta.outputs.sbom_spdx_file }} - upload-artifact: true - upload-release-assets: false - dependency-snapshot: false - - - name: Generate CycloneDX SBOM Using Syft - uses: anchore/sbom-action@v0.13.4 - id: sbom_cyclonedx - with: - image: ${{ steps.meta.outputs.scan_image }} - registry-username: ${{ inputs.registry_username }} - registry-password: ${{ inputs.registry_password }} - path: ${{ steps.meta.outputs.scan_dir }} - file: ${{ steps.meta.outputs.scan_file }} - format: cyclonedx-json - artifact-name: ${{ steps.meta.outputs.sbom_cyclonedx_file }} - output-file: ${{ steps.meta.outputs.sbom_cyclonedx_file }} - upload-artifact: true - upload-release-assets: false - dependency-snapshot: false - - - name: Check SBOM files existence - uses: andstor/file-existence-action@v2 - id: sbom_report - with: - files: "${{ steps.meta.outputs.sbom_spdx_file }}, ${{ steps.meta.outputs.sbom_cyclonedx_file }}" - fail: true - - # Don't fail during report generation - - name: Vulnerability analysis of SBOM - uses: anchore/scan-action@v3.3.5 - id: grype_analysis_sarif - if: ${{ steps.sbom_report.outputs.files_exists == 'true' }} - with: - sbom: ${{ steps.meta.outputs.sbom_spdx_file }} - output-format: sarif - fail-build: 'false' - severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} - - # Don't fail during report generation - # JSON format will report any ignored rules - - name: Vulnerability analysis of SBOM - uses: anchore/scan-action@v3.3.5 - id: grype_analysis_json - if: ${{ steps.sbom_report.outputs.files_exists == 'true' }} - with: - sbom: ${{ steps.meta.outputs.sbom_spdx_file }} - output-format: json - fail-build: 'false' - severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} - - - name: Check vulnerability analysis report existence - uses: andstor/file-existence-action@v2 - id: grype_report - with: - files: "${{ steps.grype_analysis_sarif.outputs.sarif }}, ${{ steps.grype_analysis_json.outputs.json }}" - fail: true - - # Grype CVE Action generates an ./results.sarif or ./results.report and no way to customize output file name - # Hack to increase readability of grype artifacts attached to workflows and releases - - name: Rename grype analysis report - shell: bash - run: | - mv ${{ steps.grype_analysis_sarif.outputs.sarif }} ${{ steps.meta.outputs.grype_sarif_file }} - mv ${{ steps.grype_analysis_json.outputs.json }} ${{ steps.meta.outputs.grype_json_file }} - - - name: Upload grype analysis report - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.meta.outputs.grype_sarif_file }} - path: | - ${{ steps.meta.outputs.grype_sarif_file }} - if-no-files-found: warn - - # Upload grype cve reports - - name: Upload grype analysis report - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.meta.outputs.grype_json_file }} - path: | - ${{ steps.meta.outputs.grype_json_file }} - if-no-files-found: warn - - # Fail based on severity and input parameters - # Notify grype quick scan results in table format - # Table format will supress any specified ignore rules - - name: Inspect Vulnerability analysis of SBOM - uses: anchore/scan-action@v3.3.5 - if: ${{ steps.sbom_report.outputs.files_exists == 'true' }} - with: - sbom: ${{ steps.meta.outputs.sbom_spdx_file }} - output-format: table - fail-build: ${{ steps.meta.outputs.global_enforce_build_failure == 'true' && steps.meta.outputs.global_enforce_build_failure || inputs.fail_build }} - severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} diff --git a/pr-previews/cleanup/action.yml b/pr-previews/cleanup/action.yml index 796695f5..f5c9fc6f 100644 --- a/pr-previews/cleanup/action.yml +++ b/pr-previews/cleanup/action.yml @@ -4,6 +4,9 @@ inputs: package: description: Package to cleanup PR versions required: true + days: + description: Only clean up the versions that are days-to-cleanup newer + default: 40 openPRs: description: List of open PRs in the repo @@ -21,12 +24,19 @@ runs: echo "package: ${pkgName}" echo "openPRs: ${openPRs}" + oldestDate=$(date -d '-${{ inputs.days }} day' +%s) + echo "oldestDate:${oldestDate}" + current=1 canDelete="true" # get the list of the "-pr." published version for the packages pkgDetails=$(npm view "${pkgName}" --json) - prVersions=($(echo ${pkgDetails}| jq -r '.versions' | grep '\-pr.'| sed 's/[,\"]//g')) + prVersions=($(echo ${pkgDetails} | jq -r '.time' | jq -r 'to_entries' | jq --arg jq_oldestDate ${oldestDate} '[.[] | select(.value |.[0:19] +"Z" | fromdateiso8601 > ($jq_oldestDate|tonumber))]' | jq '[.[] | .key]'| grep "\-pr." | tac | sed 's/[,\"]//g')) + if [[ -z "${prVersions}" ]]; then + echo "No preview versions found, exiting..." + exit 0 + fi distTags=$(echo ${pkgDetails}|jq -r '."dist-tags"') @@ -37,13 +47,18 @@ runs: echo " " echo "$((current++))/${total}" + if [[ -z "$(echo ${pkgDetails} | jq -r '.versions'|grep ${verToRemove})" ]]; then + echo "Version already removed, skip..." + continue + fi + verDetails=$(npm view "${pkgName}@${verToRemove}" --json) # validate that the version doesn't belong to open PR echo "${pkgName}@${verToRemove}" prNumber=$(echo ${verToRemove} | sed 's/.*\-pr\.//g'| cut -d'.' -f 1) - if [[ ! -z $(echo ${openPRs} | grep "\"${prNumber}\"") ]]; then + if [[ ! -z $(echo ${openPRs} | sed 's/\"//g'| sed 's/\[/,/g' | sed 's/\]/,/g' | grep ",${prNumber},") ]]; then if [[ ! -z $(echo ${distTags}|grep "${verToRemove}") ]]; then echo "${pkgName}@${verToRemove}: belongs to open PR and tagged as PR preview, skip..." continue diff --git a/pr-previews/validate/action.yaml b/pr-previews/validate/action.yaml index 00841ccc..f0f8d5e6 100644 --- a/pr-previews/validate/action.yaml +++ b/pr-previews/validate/action.yaml @@ -11,7 +11,7 @@ runs: for pkg in $(find ./ -name package.json ! -path '*/node_modules/*' ! -path '*/__template__/*') do - inPackage=$(jq -r '{dependencies: .dependencies, devDependencies: .devDependencies, peerDependencies: .peerDependencies}' ${pkg} | jq .[] | cut -d":" -f2|grep -E "\-pr\.[0-9]+\." || true) + inPackage=$(jq -r '{dependencies: .dependencies, devDependencies: .devDependencies, peerDependencies: .peerDependencies}' ${pkg} | jq '.[]' | cut -d":" -f2 | grep -E "(\-pr\.[0-9]+\.|@pr\-[0-9]+)" || true) if [[ "${inPackage}" != "" ]]; then if [[ "${previewPkgsDetected}" != "" ]]; then previewPkgsDetected="${previewPkgsDetected}\n" diff --git a/security-actions/scan-docker-image/action.yml b/security-actions/scan-docker-image/action.yml index 809337f2..8c6c048c 100644 --- a/security-actions/scan-docker-image/action.yml +++ b/security-actions/scan-docker-image/action.yml @@ -6,7 +6,7 @@ inputs: description: 'prefix for generated scan artifacts' required: false default: '' - dir: + dir: description: 'Speicify a directory to be scanned. This is mutually exclusive to file and image' required: false default: '' @@ -92,7 +92,7 @@ runs: with: image: ${{ steps.meta.outputs.scan_image }} registry-username: ${{ inputs.registry_username }} - registry-password: ${{ inputs.registry_password }} + registry-password: ${{ inputs.registry_password }} path: ${{ steps.meta.outputs.scan_dir }} file: ${{ steps.meta.outputs.scan_file }} format: cyclonedx-json @@ -101,14 +101,14 @@ runs: upload-artifact: true upload-release-assets: false dependency-snapshot: false - + - name: Check SBOM files existence uses: andstor/file-existence-action@v2 id: sbom_report with: files: "${{ steps.meta.outputs.sbom_spdx_file }}, ${{ steps.meta.outputs.sbom_cyclonedx_file }}" fail: true - + # Don't fail during report generation - name: Vulnerability analysis of SBOM uses: anchore/scan-action@v3.3.6 @@ -131,14 +131,14 @@ runs: output-format: json fail-build: 'false' severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} - + - name: Check vulnerability analysis report existence uses: andstor/file-existence-action@v2 id: grype_report with: files: "${{ steps.grype_analysis_sarif.outputs.sarif }}, ${{ steps.grype_analysis_json.outputs.json }}" fail: true - + # Grype CVE Action generates an ./results.sarif or ./results.report and no way to customize output file name # Hack to increase readability of grype artifacts attached to workflows and releases - name: Rename grype analysis report @@ -146,15 +146,15 @@ runs: run: | mv ${{ steps.grype_analysis_sarif.outputs.sarif }} ${{ steps.meta.outputs.grype_sarif_file }} mv ${{ steps.grype_analysis_json.outputs.json }} ${{ steps.meta.outputs.grype_json_file }} - + - name: Upload grype analysis report uses: actions/upload-artifact@v3 with: name: ${{ steps.meta.outputs.grype_sarif_file }} path: | ${{ steps.meta.outputs.grype_sarif_file }} - if-no-files-found: warn - + if-no-files-found: warn + # Upload grype cve reports - name: Upload grype analysis report uses: actions/upload-artifact@v3 @@ -175,7 +175,7 @@ runs: id: cis_json with: entrypoint: trivy - args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f json --severity ${{ env.severity }} -o ${{ steps.meta.outputs.cis_json_file }}" + args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f json --severity ${{ env.severity }} --ignore-unfixed -o ${{ steps.meta.outputs.cis_json_file }}" env: compliance: docker-cis severity: ${{ steps.meta.outputs.global_severity_cutoff }} @@ -205,7 +205,7 @@ runs: uses: docker://ghcr.io/aquasecurity/trivy:0.37.2 with: entrypoint: trivy - args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f table --severity ${{ env.severity }} --exit-code ${{ env.exit-code }}" + args: "image ${{ env.input }} ${{ steps.meta.outputs.scan_image }} --compliance ${{ env.compliance }} -f table --severity ${{ env.severity }} --ignore-unfixed --exit-code ${{ env.exit-code }}" env: exit-code: ${{ (steps.meta.outputs.global_enforce_build_failure == 'true' || inputs.fail_build == 'true') && '1' || '0' }} compliance: docker-cis diff --git a/security-actions/scan-rust/README.md b/security-actions/scan-rust/README.md new file mode 100644 index 00000000..26564789 --- /dev/null +++ b/security-actions/scan-rust/README.md @@ -0,0 +1,75 @@ +# Rust SCA + +This action uses grype for source code analysis. It will only support scanning source code directories / files and will not support the container images + + +The action runs the following: +- SCA and CVE analysis using Grype +- Uploads SCA results to Github Security for public repiositories + +## Inputs + +```yaml +asset_prefix: + description: 'prefix for generated artifacts' + required: false + default: '' +dir: + description: 'Speicify a directory to be checked and scanned' + required: false + default: '.' +fail_build: + description: 'fail the build if the vulnerability is above the severity cutoff' + required: false + default: false + type: choice + options: + - 'true' + - 'false' +``` + +## Outputs: +- SARIF upload to github code scanning for public repositories +- Console log workflow output / Github check for reporting + +## Detailed example + +```yaml +name: Rust SCA + +on: + pull_request: {} + workflow_dispatch: {} + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + rust: + name: Rust SCA + runs-on: ubuntu-20.04 + + permissions: + # required for all workflows + security-events: write + checks: write + pull-requests: write + # only required for workflows in private repositories + actions: read + contents: read + + if: (github.actor != 'dependabot[bot]') + + steps: + - name: Checkout source code + uses: actions/checkout@v3 + + - name: Source Code analysis + uses: Kong/public-shared-actions/security-actions/scan-rust@main + with: + asset_prefix: 'atc-router' +``` \ No newline at end of file diff --git a/security-actions/scan-rust/action.yml b/security-actions/scan-rust/action.yml new file mode 100644 index 00000000..1c57a862 --- /dev/null +++ b/security-actions/scan-rust/action.yml @@ -0,0 +1,95 @@ +name: Rust SCA +description: Rust SCA using grype +author: 'Kong' +inputs: + asset_prefix: + description: 'prefix for generated artifacts' + required: false + default: '' + dir: + description: 'Speicify a scan directory that must contain cargo.lock and cargo.toml' + required: false + default: '.' + fail_build: + description: 'fail the build if the vulnerability is above the severity cutoff' + required: false + default: false + type: choice + options: + - 'true' + - 'false' + codeql_upload: + description: 'Toggle to upload results to Github code scanning for public repositories' + required: false + default: true + type: choice + options: + - 'true' + - 'false' + +outputs: + grype-json-report: + description: 'vulnerability json report' + value: ${{ steps.grype_analysis.outputs.json }} + grype-sarif-report: + description: 'vulnerability sarif report' + value: ${{ steps.grype_analysis.outputs.sarif }} + +runs: + using: composite + steps: + + - name: Set Scan Job Metadata + shell: bash + id: meta + env: + DIR: ${{ inputs.dir }} + ASSET_PREFIX: ${{ inputs.asset_prefix }} + run: $GITHUB_ACTION_PATH/scripts/scan-metadata.sh + + # Don't fail during report generation + - name: Vulnerability analysis of SBOM + uses: anchore/scan-action@v3.3.5 + continue-on-error: true + id: scan + with: + path: ${{ steps.meta.outputs.scan_dir }} + output-format: sarif + fail-build: 'false' + severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} + add-cpes-if-none: true + + - name: Publish SARIF to github code scanning + if: ${{ always() && inputs.codeql_upload == 'true' && github.event.repository.visibility == 'public' }} + continue-on-error: true + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.scan.outputs.sarif }} + category: sca_rust + + # Grype CVE Action generates an ./results.sarif or ./results.report and no way to customize output file name + # Hack to increase readability of grype artifacts attached to workflows and releases + - name: Rename grype analysis report + shell: bash + run: | + mv ${{ steps.scan.outputs.sarif }} ${{ steps.meta.outputs.grype_sarif_file }} + + - name: Publish SARIF to github workflow artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.meta.outputs.grype_sarif_file }} + path: | + ${{ steps.meta.outputs.grype_sarif_file }} + if-no-files-found: warn + + # Fail based on severity and input parameters + # Notify grype quick scan results in table format + # Table format will supress any specified ignore rules + - name: Vulnerability Report + uses: anchore/scan-action@v3.3.5 + with: + path: ${{ steps.meta.outputs.scan_dir }} + output-format: table + fail-build: ${{ steps.meta.outputs.global_enforce_build_failure == 'true' && steps.meta.outputs.global_enforce_build_failure || inputs.fail_build }} + severity-cutoff: ${{ steps.meta.outputs.global_severity_cutoff }} diff --git a/code-check-actions/rustcheck/scripts/scan-metadata.sh b/security-actions/scan-rust/scripts/scan-metadata.sh similarity index 68% rename from code-check-actions/rustcheck/scripts/scan-metadata.sh rename to security-actions/scan-rust/scripts/scan-metadata.sh index e96bf7a1..8338ecfa 100755 --- a/code-check-actions/rustcheck/scripts/scan-metadata.sh +++ b/security-actions/scan-rust/scripts/scan-metadata.sh @@ -2,8 +2,6 @@ set -euo pipefail -readonly spdx_ext="sbom.spdx.json" -readonly cyclonedx_ext="sbom.cyclonedx.json" readonly cve_json_ext="cve-report.json" readonly cve_sarif_ext="cve-report.sarif" @@ -17,21 +15,12 @@ fi if [[ -n ${DIR} ]]; then echo "scan_dir=${DIR}" >> $GITHUB_OUTPUT - echo "lint_path=${DIR}/Cargo.toml" >> $GITHUB_OUTPUT -fi - -if [[ -n ${FILE} ]]; then - echo "scan_file=${FILE}" >> $GITHUB_OUTPUT fi if [[ -n ${ASSET_PREFIX} ]]; then - echo "sbom_spdx_file=${ASSET_PREFIX##*/}-${spdx_ext}" >> $GITHUB_OUTPUT - echo "sbom_cyclonedx_file=${ASSET_PREFIX##*/}-${cyclonedx_ext}" >> $GITHUB_OUTPUT echo "grype_json_file=${ASSET_PREFIX##*/}-${cve_json_ext}" >> $GITHUB_OUTPUT echo "grype_sarif_file=${ASSET_PREFIX##*/}-${cve_sarif_ext}" >> $GITHUB_OUTPUT else - echo "sbom_spdx_file=${spdx_ext}" >> $GITHUB_OUTPUT - echo "sbom_cyclonedx_file=${cyclonedx_ext}" >> $GITHUB_OUTPUT echo "grype_json_file=${cve_json_ext}" >> $GITHUB_OUTPUT echo "grype_sarif_file=${cve_sarif_ext}" >> $GITHUB_OUTPUT fi diff --git a/security-actions/semgrep/README.md b/security-actions/semgrep/README.md new file mode 100644 index 00000000..6c8dc4be --- /dev/null +++ b/security-actions/semgrep/README.md @@ -0,0 +1,50 @@ +# Semgrep SAST - Github Action + +This action uses Semgrep CI command to scan all supported platforms on a specified scan path + +The action runs the following: +- Self detects config rules from semgrep registry +- Applies any additional arguments / configuration rules passed to semgrep +- Provides a optional input to fail downstream builds based on semgrep findings + +## Action Output +- Report Semgrep Finding Summary as Console output +- Report Findings + - Private repositories: workflow artifact file + - Public repositories: Github Security tab +- The failure mode of build is configurable based on shared action outcome +## Detailed example + +```yaml +name: Semgrep + +on: + pull_request: {} + push: + branches: + - master + - main + workflow_dispatch: {} + + +jobs: + semgrep: + name: SAST + runs-on: ubuntu-20.04 + permissions: + # required for all workflows + security-events: write + # only required for workflows in private repositories + actions: read + contents: read + + if: (github.actor != 'dependabot[bot]') + + steps: + - uses: actions/checkout@v3 + - uses: Kong/public-shared-actions/security-actions/semgrep@main + with: + additional_config: '--config p/rust' + + +``` \ No newline at end of file diff --git a/security-actions/semgrep/action.yml b/security-actions/semgrep/action.yml new file mode 100644 index 00000000..8494a402 --- /dev/null +++ b/security-actions/semgrep/action.yml @@ -0,0 +1,61 @@ +name: Semgrep SAST +description: Semgrep SAST +author: 'Kong' +inputs: + additional_config: + description: 'Provide additional config to semgrep ci command using --config' + required: false + default: '' + codeql_upload: + description: 'Toggle to upload results to Github code scanning for public repositories' + required: false + default: true + type: choice + options: + - 'true' + - 'false' + fail_on_findings: + description: 'Fail build / job on semgrep findings/errors' + required: false + default: false + type: choice + options: + - 'true' + - 'false' +runs: + using: 'composite' + steps: + + - name: SAST Scan + uses: docker://returntocorp/semgrep + id: semgrep + continue-on-error: true + with: + args: "semgrep ci --config auto --sarif -o semgrep_${{github.sha}}.sarif --no-autofix ${{ inputs.additional_config }}" + + # Upload grype cve reports + - name: Upload Semgrep SARIF to Workflow + if: always() + uses: actions/upload-artifact@v3 + with: + name: semgrep_sast.zip + path: | + semgrep_${{github.sha}}.sarif + if-no-files-found: warn + + - name: Upload SARIF to Github Code Scanning + if: ${{ always() && inputs.codeql_upload == 'true' && github.event.repository.visibility == 'public' }} + uses: github/codeql-action/upload-sarif@v2 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: semgrep_${{github.sha}}.sarif + # Optional category for the results + # Used to differentiate multiple results for one commit + category: sast_semgrep + + - name: Fail on findings + if: ${{ always() && inputs.fail_on_findings == 'true' && steps.semgrep.outcome == 'failure' }} + shell: bash + run: | + echo "::error::Semgrep has detected findings. For findings, check workflow artifact: semgrep_sast.zip / Github Security analysis" + exit 1