diff --git a/.github/workflows/maven-mend-ci.yml b/.github/workflows/mend-ci.yml
similarity index 77%
rename from .github/workflows/maven-mend-ci.yml
rename to .github/workflows/mend-ci.yml
index dbf48ae..02c576e 100644
--- a/.github/workflows/maven-mend-ci.yml
+++ b/.github/workflows/mend-ci.yml
@@ -1,18 +1,8 @@
-name: Mend CLI scan for Maven
+name: Mend CLI scan
on:
workflow_call:
inputs:
- java_version:
- description: "The Java version to use to compile. Default: 21"
- required: false
- type: string
- default: "21"
- maven_version:
- description: "The Maven version to use. Defaults to version of the runner image"
- required: false
- type: string
- default: "3.9.14"
SCA:
required: true
type: boolean
@@ -23,18 +13,13 @@ on:
SAST:
required: true
type: boolean
- mode:
- description: "'fresh' (checkout + build + scan) or 'deferred' (consume artifact + scan)"
- required: false
- type: string
- default: "fresh"
triggering_run_id:
- description: "workflow_run id to pull artifacts from (required for mode='deferred')"
+ description: "workflow_run id to pull artifacts from"
required: false
type: string
default: ""
pr_feedback:
- description: "PR check and comment feedback (deferred mode only)"
+ description: "Whether to add PR check and comment feedback"
required: false
type: boolean
default: false
@@ -70,51 +55,32 @@ jobs:
security-events: write
steps:
- # Fresh mode: checkout + build
-
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- if: inputs.mode == 'fresh'
- with:
- persist-credentials: false
-
- - uses: project-ncl/shared-github-actions/.github/actions/maven-build@94481b379fd7ddda5fe363d1c1d5fc311930c607 # main
- if: inputs.mode == 'fresh'
- with:
- java_version: ${{ inputs.java_version }}
- build_command: "mvn -B -V clean install -DskipTests"
- maven_version: ${{ inputs.maven_version }}
-
- # Deferred mode: fetch PR metadata and build artifact
-
- name: Download PR metadata
- if: inputs.mode == 'deferred'
+ if: inputs.pr_feedback
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: pr-metadata
path: pr-metadata
- run-id: ${{ inputs.triggering_run_id }}
+ run-id: ${{ inputs.triggering_run_id || github.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Read PR metadata
- if: inputs.mode == 'deferred'
+ if: inputs.pr_feedback
id: metadata
run: |
echo "pr_number=$(cat pr-metadata/pr-number)" >> "$GITHUB_OUTPUT"
echo "pr_sha=$(cat pr-metadata/pr-sha)" >> "$GITHUB_OUTPUT"
- - name: Download PR build artifact
- if: inputs.mode == 'deferred'
+ - name: Download build artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: pr-build
path: .
- run-id: ${{ inputs.triggering_run_id }}
+ run-id: ${{ inputs.triggering_run_id || github.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- # Deferred mode: create in-progress check-run
-
- name: Create in-progress check-run
- if: inputs.mode == 'deferred' && inputs.pr_feedback
+ if: inputs.pr_feedback
id: check
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # 9.0.0
env:
@@ -131,27 +97,23 @@ jobs:
});
return check.id;
- # Common: run Mend scan
-
- name: Run Mend CLI scan
uses: project-ncl/shared-github-actions/.github/actions/mend@94481b379fd7ddda5fe363d1c1d5fc311930c607 # main
with:
PROJECT_NAME: ${{ github.event.repository.name }}
TAGS: >-
- ${{ inputs.mode == 'deferred'
+ ${{ inputs.pr_feedback
&& format('trigger:pr, pr:{0}, run:{1}', steps.metadata.outputs.pr_number, github.run_id)
|| format('trigger:{0}, run:{1}', github.event_name, github.run_id) }}
SCA: ${{ inputs.SCA }}
SCA_REACHABILITY: ${{ inputs.SCA_REACHABILITY }}
SAST: ${{ inputs.SAST }}
- source_ref: ${{ inputs.mode == 'deferred' && format('refs/pull/{0}/head', steps.metadata.outputs.pr_number) || '' }}
- source_sha: ${{ inputs.mode == 'deferred' && steps.metadata.outputs.pr_sha || '' }}
-
- # Deferred mode: update check-run + PR comment with results
+ source_ref: ${{ steps.metadata.outputs.pr_number && format('refs/pull/{0}/head', steps.metadata.outputs.pr_number) || '' }}
+ source_sha: ${{ steps.metadata.outputs.pr_sha || '' }}
- name: Build result summary
id: summary
- if: ${{ !cancelled() && inputs.mode == 'deferred' && inputs.pr_feedback }}
+ if: ${{ !cancelled() && inputs.pr_feedback }}
run: |
SCA_LOG="$HOME/.mend/logs/sca-results.txt"
SAST_LOG="$HOME/.mend/logs/sast-results.sarif"
@@ -229,7 +191,7 @@ jobs:
echo "overall=success" >> "$GITHUB_OUTPUT"
- name: Update check-run
- if: ${{ !cancelled() && inputs.mode == 'deferred' && inputs.pr_feedback }}
+ if: ${{ !cancelled() && inputs.pr_feedback }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # 9.0.0
env:
CHECK_ID: ${{ steps.check.outputs.result }}
@@ -251,7 +213,7 @@ jobs:
});
- name: Post or update PR comment
- if: ${{ !cancelled() && inputs.mode == 'deferred' && inputs.pr_feedback }}
+ if: ${{ !cancelled() && inputs.pr_feedback }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # 9.0.0
env:
PR_NUMBER: ${{ steps.metadata.outputs.pr_number }}
diff --git a/.github/workflows/npm-ci.yml b/.github/workflows/npm-ci.yml
new file mode 100644
index 0000000..5732597
--- /dev/null
+++ b/.github/workflows/npm-ci.yml
@@ -0,0 +1,92 @@
+name: NPM CI
+
+on:
+ workflow_call:
+ inputs:
+ fetch_all_commits:
+ description: "Whether to fetch all commits. Default: false"
+ required: false
+ type: boolean
+ default: false
+ node_version:
+ description: "The Node.js version to use. Default: 22.x"
+ required: false
+ type: string
+ default: "22.x"
+ build_command:
+ description: "The build command to use. Default: npm ci and npm run build"
+ required: false
+ type: string
+ default: "npm ci && npm run build"
+ test_command:
+ description: "The command to use for tests. Default: null"
+ required: false
+ type: string
+ formatter_command:
+ description: "The command to use for formatting. Default: null"
+ required: false
+ type: string
+ upload_artifacts:
+ description: "Whether to upload artifacts and their metadata. Default: false"
+ required: false
+ type: boolean
+ default: false
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.node_version }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: ${{ inputs.fetch_all_commits == true && '0' || '1' }}
+ persist-credentials: false
+
+ - uses: project-ncl/shared-github-actions/.github/actions/npm-build@8ba48d272f8e53b55e5a266a4c3feeab6e7f0526 # main
+ with:
+ node_version: ${{ inputs.node_version }}
+ build_command: ${{ inputs.build_command }}
+
+ - if: inputs.test_command
+ env:
+ INPUTS_TEST_COMMAND: ${{ inputs.test_command }}
+ run: bash -c "${INPUTS_TEST_COMMAND}"
+
+ - if: inputs.formatter_command
+ env:
+ INPUTS_FORMATTER_COMMAND: ${{ inputs.formatter_command }}
+ run: bash -c "${INPUTS_FORMATTER_COMMAND}"
+
+ - name: Save PR metadata
+ if: inputs.upload_artifacts
+ env:
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ PR_SHA: ${{ github.event.pull_request.head.sha }}
+ run: |
+ mkdir -p pr-metadata
+ echo "$PR_NUMBER" > pr-metadata/pr-number
+ echo "$PR_SHA" > pr-metadata/pr-sha
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ if: inputs.upload_artifacts
+ with:
+ name: pr-build
+ path: |
+ .
+ !.git
+ !pr-metadata
+ retention-days: 1
+
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ if: inputs.upload_artifacts
+ with:
+ name: pr-metadata
+ path: pr-metadata
+ retention-days: 1
diff --git a/README.md b/README.md
index 2ec1e51..3978966 100644
--- a/README.md
+++ b/README.md
@@ -43,15 +43,22 @@ the Java version etc. It is possible to use this within a matrix job.
```
-## Maven Mend
-Workflow to run Mend analysis, both SCA (Software Composition Analysis) and SAST (Static Application Security Testing), on Maven projects. Because it has to have access to secrets in the organization or repository, it has two modes: `fresh` and `deferred`.
+## NPM CI (`npm-ci.yml`)
+Standard CI workflow for NPM projects.
-Fresh mode checkouts the code, builds the Maven project, and runs the Mend analysis. It is designed for cronjob schedule, and push to main workflow runs - because for those, the secrets are accessible.
+- **Tasks**: Checkout code, set up Node.js, set up NPM, run build command, optionally run tests, optionally check for code formatting errors, and optionally push build artifact (which is used by Mend workflow).
-Workflows run in the context of the PR from a fork do not have access to the secrets. For that use-case, deferred mode exists. It is meant to be executed `on: workflow_run` depending on Maven CI workflow with `upload_artifact` set to `true` - this way, the Maven Mend workflow is run in the context of the base repository. It downloads saved PR metadata and build artifact, sets check-run on the PR, runs the Mend analysis, and posts PR comment.
+## Mend CI (`mend-ci.yml`)
+Workflow to run Mend analysis, both SCA (Software Composition Analysiss) and SAST (Static Application Security Testing), on Maven projects. Because it has to have access to secrets in the organization or repository, on Pull Requests, it is meant to run `on: workflow_run`.
+
+It depends on some build workflow with `upload_artifact` set to `true`, and before analysis, downloads an build artifact.
+
+If `pr_feedback` is `false`, it downloads the build artifact, and runs the Mend analysis. This is meant for cronjob schedule, and push to main workflow runs.
+
+Workflows run in the context of the PR from a fork do not have access to the secrets. It is meant to be executed `on: workflow_run` - this way, the Mend workflow is run in the context of the base repository. `pr_feedback` should be set to `true` and `triggering_run_id` set to ID of a triggering workflow. It downloads saved PR metadata and build artifact, sets check-run on the PR, runs the Mend analysis, and posts PR comment.
-Example of 'fresh' mode usage
+Example of push to main and cronjob usage
```yaml
name: Mend CLI scan for Maven
@@ -71,8 +78,19 @@ permissions:
security-events: write
jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@
+ - uses: project-ncl/shared-github-actions/.github/actions/maven-build@
+ - uses: actions/upload-artifact@
+ with:
+ name: pr-build
+ path: .
+
call-maven-mend-ci:
- uses: project-ncl/shared-github-actions/.github/workflows/maven-mend-ci.yml@
+ needs: build
+ uses: project-ncl/shared-github-actions/.github/workflows/mend-ci.yml@
with:
SCA: true
SAST: true
@@ -86,7 +104,7 @@ jobs:
-Example of 'deferred' mode usage
+Example of PR usage
```yaml
name: Java CI with Maven
@@ -126,11 +144,10 @@ concurrency:
jobs:
scan:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request'
- uses: project-ncl/shared-github-actions/.github/workflows/maven-mend-ci.yml@
+ uses: project-ncl/shared-github-actions/.github/workflows/mend-ci.yml@
with:
SCA: true
SAST: true
- mode: deferred
triggering_run_id: ${{ github.event.workflow_run.id }}
pr_feedback: true
secrets: