From aac982984d2d047b811001127ecffdd22a74f3e0 Mon Sep 17 00:00:00 2001 From: lucas Date: Fri, 10 Oct 2025 17:38:50 +0100 Subject: [PATCH 01/19] branch cleanup --- danger/README.md | 2 ++ danger/action.yml | 54 ++++++++++++++++++++++++++++++++++++++++---- danger/dangerfile.js | 27 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/danger/README.md b/danger/README.md index daaee7d..3793178 100644 --- a/danger/README.md +++ b/danger/README.md @@ -29,6 +29,8 @@ jobs: * type: string * required: false * default: `${{ github.token }}` + * extra-dangerfile: Path to an additional dangerfile to run custom checks. + * extra-install-packages: Additional packages that are required by the extra-dangerfile, you can find a list of packages here: https://packages.debian.org/search?suite=bookworm&keywords=curl. ## Outputs diff --git a/danger/action.yml b/danger/action.yml index dcdc110..0fbc118 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -7,6 +7,14 @@ inputs: description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}' required: false default: ${{ github.token }} + extra-dangerfile: + description: 'Path to additional dangerfile to run after the main checks' + type: string + required: false + extra-install-packages: + description: 'Additional apt packages to install in the DangerJS container (space-separated package names)' + type: string + required: false outputs: outcome: @@ -22,12 +30,31 @@ runs: token: ${{ inputs.api-token }} fetch-depth: 0 + # Read the Danger version from the properties file + - name: Get Danger version + id: config + shell: pwsh + run: Get-Content '${{ github.action_path }}/danger.properties' | Tee-Object $env:GITHUB_OUTPUT -Append + + # Validate extra-install-packages to prevent code injection + - name: Validate package names + if: ${{ inputs.extra-install-packages }} + shell: bash + run: | + packages="${{ inputs.extra-install-packages }}" + # Only allow alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces + if ! echo "$packages" | grep -E '^[a-zA-Z0-9._+-]+( [a-zA-Z0-9._+-]+)*$' > /dev/null; then + echo "::error::Invalid package names in extra-install-packages. Only alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces are allowed." + exit 1 + fi + # Using a pre-built docker image in GitHub container registry instead of NPM to reduce possible attack vectors. - - name: Run DangerJS - id: danger + - name: Setup container shell: bash run: | - docker run \ + # Start a detached container with all necessary volumes and environment variables + docker run -td --name danger \ + --entrypoint /bin/bash \ --volume ${{ github.workspace }}:/github/workspace \ --volume ${{ github.action_path }}:${{ github.action_path }} \ --volume ${{ github.event_path }}:${{ github.event_path }} \ @@ -36,5 +63,22 @@ runs: -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ -e GITHUB_TOKEN="${{ inputs.api-token }}" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - ghcr.io/danger/danger-js:11.3.1 \ - --failOnErrors --dangerfile ${{ github.action_path }}/dangerfile.js \ No newline at end of file + -e EXTRA_DANGERFILE_INPUT="${{ inputs.extra-dangerfile }}" \ + ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ + -c "sleep infinity" + + - name: Setup additional packages + if: ${{ inputs.extra-install-packages }} + shell: bash + run: | + docker exec --user root danger apt-get update + echo "Installing packages: ${{ inputs.extra-install-packages }}" + docker exec --user root danger sh -c "apt-get install -y ${{ inputs.extra-install-packages }}" + echo "All additional packages installed successfully." + + - name: Run DangerJS + id: danger + shell: bash + run: | + trap "docker rm -f danger || true" EXIT + docker exec --user $(id -u) danger danger ci --fail-on-errors --dangerfile ${{ github.action_path }}/dangerfile.js \ No newline at end of file diff --git a/danger/dangerfile.js b/danger/dangerfile.js index 997a9c0..f82c06a 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -1,4 +1,5 @@ const { getFlavorConfig, extractPRFlavor } = require('./dangerfile-utils.js'); +const fs = require('fs'); const headRepoName = danger.github.pr.head.repo.git_url; const baseRepoName = danger.github.pr.base.repo.git_url; @@ -186,10 +187,36 @@ async function checkActionsArePinned() { } } +async function CheckFromExternalChecks() { + // Get the external dangerfile path from environment variable (passed via workflow input) + // Priority: EXTRA_DANGERFILE (absolute path) -> EXTRA_DANGERFILE_INPUT (relative path) + const customPath = process.env.EXTRA_DANGERFILE || process.env.EXTRA_DANGERFILE_INPUT; + console.log(`::debug:: Checking from external checks: ${customPath}`); + if (customPath) { + try { + const extraModule = require(`/github/workspace/${customPath}`); + await extraModule({ + fail: fail, + warn: warn, + message: message, + markdown: markdown, + danger: danger, + }); + } catch (err) { + if (err.message && err.message.includes('Cannot use import statement outside a module')) { + warn(`External dangerfile uses ES6 imports. Please convert to CommonJS syntax (require/module.exports) or use .mjs extension with proper module configuration.\nFile: ${customPath}`); + } else { + warn(`Could not load custom Dangerfile: ${customPath}\n${err}`); + } + } + } +} + async function checkAll() { await checkDocs(); await checkChangelog(); await checkActionsArePinned(); + await CheckFromExternalChecks(); } schedule(checkAll); From 7e4598b6734cf313950aa45f614229eca81ab59f Mon Sep 17 00:00:00 2001 From: LucasZF Date: Tue, 14 Oct 2025 16:39:37 +0100 Subject: [PATCH 02/19] Update danger/action.yml Co-authored-by: Ivan Dlugos <6349682+vaind@users.noreply.github.com> --- danger/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 08e6d8f..5a945e1 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -81,5 +81,4 @@ runs: id: danger shell: bash run: | - trap "docker rm -f danger || true" EXIT docker exec --user $(id -u) danger danger ci --fail-on-errors --dangerfile ${{ github.action_path }}/dangerfile.js \ No newline at end of file From c4c0849b0b6f5bb14eec718c3637abc86211ad8a Mon Sep 17 00:00:00 2001 From: LucasZF Date: Tue, 14 Oct 2025 16:40:47 +0100 Subject: [PATCH 03/19] Update danger/action.yml Co-authored-by: seer-by-sentry[bot] <157164994+seer-by-sentry[bot]@users.noreply.github.com> --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 5a945e1..a6318a6 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -48,7 +48,7 @@ runs: exit 1 fi -# Using a pre-built docker image in GitHub container registry instead of NPM to reduce possible attack vectors. + # Using a pre-built docker image in GitHub container registry instead of NPM to reduce possible attack vectors. - name: Setup container shell: bash run: | From bb559dbcbc93cc1d830508890eb30293d10ff2f7 Mon Sep 17 00:00:00 2001 From: LucasZF Date: Tue, 14 Oct 2025 16:43:03 +0100 Subject: [PATCH 04/19] Update danger/action.yml Co-authored-by: seer-by-sentry[bot] <157164994+seer-by-sentry[bot]@users.noreply.github.com> --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index a6318a6..2f8f33e 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -74,7 +74,7 @@ runs: run: | docker exec --user root danger apt-get update echo "Installing packages: ${{ inputs.extra-install-packages }}" - docker exec --user root danger sh -c "apt-get install -y ${{ inputs.extra-install-packages }}" + docker exec --user root danger sh -c "set -e && apt-get install -y --no-install-recommends ${{ inputs.extra-install-packages }}" echo "All additional packages installed successfully." - name: Run DangerJS From e7650139d3194931e86ad79d66edab86e68d7391 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 14 Oct 2025 17:13:19 +0100 Subject: [PATCH 05/19] reviewed changes --- danger/README.md | 28 +++++++++++++++++++++++++--- danger/action.yml | 1 - danger/dangerfile.js | 18 ++++++++++++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/danger/README.md b/danger/README.md index 3793178..4f98173 100644 --- a/danger/README.md +++ b/danger/README.md @@ -29,8 +29,16 @@ jobs: * type: string * required: false * default: `${{ github.token }}` - * extra-dangerfile: Path to an additional dangerfile to run custom checks. - * extra-install-packages: Additional packages that are required by the extra-dangerfile, you can find a list of packages here: https://packages.debian.org/search?suite=bookworm&keywords=curl. + +* `extra-dangerfile`: Path to an additional dangerfile to run custom checks. + * type: string + * required: false + * default: "" + +* `extra-install-packages`: Additional packages that are required by the extra-dangerfile, you can find a list of packages here: https://packages.debian.org/search?suite=bookworm&keywords=curl. + * type: string + required: false + default: "" ## Outputs @@ -54,4 +62,18 @@ The Danger action runs the following checks: - **Conventional commits**: Validates commit message format and PR title conventions - **Cross-repo links**: Checks for proper formatting of links in changelog entries -For detailed rule implementations, see [dangerfile.js](dangerfile.js). \ No newline at end of file +For detailed rule implementations, see [dangerfile.js](dangerfile.js). + +## Extra Danger File + +When using an extra dangerfile, the file must be inside the repository and written in CommonJS syntax. You can use the following snippet to export your dangerfile: + +```JavaScript +module.exports = async function ({ fail, warn, message, markdown, danger }) { + ... + const gitUrl = danger.github.pr.head.repo.git_url; + ... + warn('...'); +} + +``` \ No newline at end of file diff --git a/danger/action.yml b/danger/action.yml index 2f8f33e..d6c281e 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -65,7 +65,6 @@ runs: -e DANGER_DISABLE_TRANSPILATION="true" \ -e EXTRA_DANGERFILE_INPUT="${{ inputs.extra-dangerfile }}" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ - ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" - name: Setup additional packages diff --git a/danger/dangerfile.js b/danger/dangerfile.js index f82c06a..7284ebe 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -1,5 +1,4 @@ const { getFlavorConfig, extractPRFlavor } = require('./dangerfile-utils.js'); -const fs = require('fs'); const headRepoName = danger.github.pr.head.repo.git_url; const baseRepoName = danger.github.pr.base.repo.git_url; @@ -190,11 +189,22 @@ async function checkActionsArePinned() { async function CheckFromExternalChecks() { // Get the external dangerfile path from environment variable (passed via workflow input) // Priority: EXTRA_DANGERFILE (absolute path) -> EXTRA_DANGERFILE_INPUT (relative path) - const customPath = process.env.EXTRA_DANGERFILE || process.env.EXTRA_DANGERFILE_INPUT; - console.log(`::debug:: Checking from external checks: ${customPath}`); - if (customPath) { + const extraDangerFilePath = process.env.EXTRA_DANGERFILE || process.env.EXTRA_DANGERFILE_INPUT; + console.log(`::debug:: Checking from external checks: ${extraDangerFilePath}`); + if (extraDangerFilePath) { try { + const workspaceDir = '/github/workspace'; + const customPath = path.join('/github/workspace', extraDangerFilePath); + if (!customPath.startsWith(workspaceDir)) { + fail(`Invalid dangerfile path: ${customPath}. Path traversal is not allowed.`); + return; + } + const extraModule = require(`/github/workspace/${customPath}`); + if (typeof extraModule !== 'function') { + warn(`EXTRA_DANGERFILE must export a function at ${customPath}`); + return; + } await extraModule({ fail: fail, warn: warn, From ccf73eb1caec642ef9439fa4099dc55190a7cd35 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 14 Oct 2025 17:18:19 +0100 Subject: [PATCH 06/19] fix customPath ref --- danger/dangerfile.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/danger/dangerfile.js b/danger/dangerfile.js index 7284ebe..e42f23e 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -195,12 +195,13 @@ async function CheckFromExternalChecks() { try { const workspaceDir = '/github/workspace'; const customPath = path.join('/github/workspace', extraDangerFilePath); + if (!customPath.startsWith(workspaceDir)) { fail(`Invalid dangerfile path: ${customPath}. Path traversal is not allowed.`); return; } - const extraModule = require(`/github/workspace/${customPath}`); + const extraModule = require(customPath); if (typeof extraModule !== 'function') { warn(`EXTRA_DANGERFILE must export a function at ${customPath}`); return; @@ -216,7 +217,7 @@ async function CheckFromExternalChecks() { if (err.message && err.message.includes('Cannot use import statement outside a module')) { warn(`External dangerfile uses ES6 imports. Please convert to CommonJS syntax (require/module.exports) or use .mjs extension with proper module configuration.\nFile: ${customPath}`); } else { - warn(`Could not load custom Dangerfile: ${customPath}\n${err}`); + warn(`Could not load custom Dangerfile: ${extraDangerFilePath}\n${err}`); } } } From 8c62a427084eb06619779083d987a807b8486060 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 14 Oct 2025 17:27:13 +0100 Subject: [PATCH 07/19] load path --- danger/dangerfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/danger/dangerfile.js b/danger/dangerfile.js index e42f23e..2bcb133 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -194,6 +194,7 @@ async function CheckFromExternalChecks() { if (extraDangerFilePath) { try { const workspaceDir = '/github/workspace'; + const path = require('path'); const customPath = path.join('/github/workspace', extraDangerFilePath); if (!customPath.startsWith(workspaceDir)) { From 2cc1eb3f44384670986142fdc1ee5495bb8074ba Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 14 Oct 2025 17:54:08 +0100 Subject: [PATCH 08/19] code ref fix / simplified transversal check --- danger/dangerfile.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/danger/dangerfile.js b/danger/dangerfile.js index 2bcb133..74303ac 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -193,14 +193,13 @@ async function CheckFromExternalChecks() { console.log(`::debug:: Checking from external checks: ${extraDangerFilePath}`); if (extraDangerFilePath) { try { - const workspaceDir = '/github/workspace'; - const path = require('path'); - const customPath = path.join('/github/workspace', extraDangerFilePath); - - if (!customPath.startsWith(workspaceDir)) { + if (extraDangerFilePath.contains(workspaceDir)) { fail(`Invalid dangerfile path: ${customPath}. Path traversal is not allowed.`); return; } + + const workspaceDir = '/github/workspace'; + const customPath = `${workspaceDir}${extraDangerFilePath}`; const extraModule = require(customPath); if (typeof extraModule !== 'function') { @@ -216,7 +215,7 @@ async function CheckFromExternalChecks() { }); } catch (err) { if (err.message && err.message.includes('Cannot use import statement outside a module')) { - warn(`External dangerfile uses ES6 imports. Please convert to CommonJS syntax (require/module.exports) or use .mjs extension with proper module configuration.\nFile: ${customPath}`); + warn(`External dangerfile uses ES6 imports. Please convert to CommonJS syntax (require/module.exports) or use .mjs extension with proper module configuration.\nFile: ${extraDangerFilePath}`); } else { warn(`Could not load custom Dangerfile: ${extraDangerFilePath}\n${err}`); } From 283729ded04d25452fca8fb086951ed0d700f414 Mon Sep 17 00:00:00 2001 From: lucas Date: Mon, 20 Oct 2025 14:26:15 +0100 Subject: [PATCH 09/19] use env fix reference use instefof instead of invalid contains use --- danger/action.yml | 21 +++++++++++++++------ danger/dangerfile.js | 10 +++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/danger/action.yml b/danger/action.yml index d6c281e..e942cc1 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -26,8 +26,10 @@ runs: steps: - name: Checkout repository uses: actions/checkout@v4 + env: + API_TOKEN: ${{ inputs.api-token }} with: - token: ${{ inputs.api-token }} + token: ${{ env.API_TOKEN }} fetch-depth: 0 # Read the Danger version from the properties file @@ -40,8 +42,10 @@ runs: - name: Validate package names if: ${{ inputs.extra-install-packages }} shell: bash + env: + EXTRA_INSTALL_PACKAGES: ${{ inputs.extra-install-packages }} run: | - packages="${{ inputs.extra-install-packages }}" + packages="$EXTRA_INSTALL_PACKAGES" # Only allow alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces if ! echo "$packages" | grep -E '^[a-zA-Z0-9._+-]+( [a-zA-Z0-9._+-]+)*$' > /dev/null; then echo "::error::Invalid package names in extra-install-packages. Only alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces are allowed." @@ -51,6 +55,9 @@ runs: # Using a pre-built docker image in GitHub container registry instead of NPM to reduce possible attack vectors. - name: Setup container shell: bash + env: + API_TOKEN: ${{ inputs.api-token }} + EXTRA_DANGERFILE: ${{ inputs.extra-dangerfile }} run: | # Start a detached container with all necessary volumes and environment variables docker run -td --name danger \ @@ -61,19 +68,21 @@ runs: --workdir /github/workspace \ --user $(id -u) \ -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ - -e GITHUB_TOKEN="${{ inputs.api-token }}" \ + -e GITHUB_TOKEN="$API_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - -e EXTRA_DANGERFILE_INPUT="${{ inputs.extra-dangerfile }}" \ + -e EXTRA_DANGERFILE_INPUT="$EXTRA_DANGERFILE" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" - name: Setup additional packages if: ${{ inputs.extra-install-packages }} shell: bash + env: + EXTRA_INSTALL_PACKAGES: ${{ inputs.extra-install-packages }} run: | docker exec --user root danger apt-get update - echo "Installing packages: ${{ inputs.extra-install-packages }}" - docker exec --user root danger sh -c "set -e && apt-get install -y --no-install-recommends ${{ inputs.extra-install-packages }}" + echo "Installing packages: $EXTRA_INSTALL_PACKAGES" + docker exec --user root danger sh -c "set -e && apt-get install -y --no-install-recommends $EXTRA_INSTALL_PACKAGES" echo "All additional packages installed successfully." - name: Run DangerJS diff --git a/danger/dangerfile.js b/danger/dangerfile.js index 74303ac..aa32d50 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -193,13 +193,13 @@ async function CheckFromExternalChecks() { console.log(`::debug:: Checking from external checks: ${extraDangerFilePath}`); if (extraDangerFilePath) { try { - if (extraDangerFilePath.contains(workspaceDir)) { + const workspaceDir = '/github/workspace'; + const customPath = `${workspaceDir}/${extraDangerFilePath}`; + + if (extraDangerFilePath.indexOf('..') !== -1) { fail(`Invalid dangerfile path: ${customPath}. Path traversal is not allowed.`); return; - } - - const workspaceDir = '/github/workspace'; - const customPath = `${workspaceDir}${extraDangerFilePath}`; + } const extraModule = require(customPath); if (typeof extraModule !== 'function') { From 5cbc268127444aa425e014f90c6c84186bde52a6 Mon Sep 17 00:00:00 2001 From: LucasZF Date: Tue, 21 Oct 2025 16:43:15 +0100 Subject: [PATCH 10/19] Apply suggestions from code review Co-authored-by: Ivan Dlugos <6349682+vaind@users.noreply.github.com> --- danger/README.md | 4 ++-- danger/action.yml | 3 +-- danger/dangerfile.js | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/danger/README.md b/danger/README.md index 4f98173..482f2a1 100644 --- a/danger/README.md +++ b/danger/README.md @@ -37,8 +37,8 @@ jobs: * `extra-install-packages`: Additional packages that are required by the extra-dangerfile, you can find a list of packages here: https://packages.debian.org/search?suite=bookworm&keywords=curl. * type: string - required: false - default: "" + * required: false + * default: "" ## Outputs diff --git a/danger/action.yml b/danger/action.yml index e942cc1..8077574 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -80,9 +80,8 @@ runs: env: EXTRA_INSTALL_PACKAGES: ${{ inputs.extra-install-packages }} run: | - docker exec --user root danger apt-get update echo "Installing packages: $EXTRA_INSTALL_PACKAGES" - docker exec --user root danger sh -c "set -e && apt-get install -y --no-install-recommends $EXTRA_INSTALL_PACKAGES" + docker exec --user root danger sh -c "set -e && apt-get update && apt-get install -y --no-install-recommends $EXTRA_INSTALL_PACKAGES" echo "All additional packages installed successfully." - name: Run DangerJS diff --git a/danger/dangerfile.js b/danger/dangerfile.js index aa32d50..ac6b471 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -186,7 +186,7 @@ async function checkActionsArePinned() { } } -async function CheckFromExternalChecks() { +async function checkFromExternalChecks() { // Get the external dangerfile path from environment variable (passed via workflow input) // Priority: EXTRA_DANGERFILE (absolute path) -> EXTRA_DANGERFILE_INPUT (relative path) const extraDangerFilePath = process.env.EXTRA_DANGERFILE || process.env.EXTRA_DANGERFILE_INPUT; @@ -227,7 +227,7 @@ async function checkAll() { await checkDocs(); await checkChangelog(); await checkActionsArePinned(); - await CheckFromExternalChecks(); + await checkFromExternalChecks(); } schedule(checkAll); From 5cdeef353f145fee21c2ac64deec0371c4b951d5 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 21 Oct 2025 16:48:16 +0100 Subject: [PATCH 11/19] applied suggestion --- danger/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/danger/action.yml b/danger/action.yml index 8077574..4d9ac72 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -56,8 +56,8 @@ runs: - name: Setup container shell: bash env: - API_TOKEN: ${{ inputs.api-token }} - EXTRA_DANGERFILE: ${{ inputs.extra-dangerfile }} + GITHUB_TOKEN: ${{ inputs.api-token }} + EXTRA_DANGERFILE_INPUT: ${{ inputs.extra-dangerfile }} run: | # Start a detached container with all necessary volumes and environment variables docker run -td --name danger \ @@ -68,9 +68,9 @@ runs: --workdir /github/workspace \ --user $(id -u) \ -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ - -e GITHUB_TOKEN="$API_TOKEN" \ + -e "$GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - -e EXTRA_DANGERFILE_INPUT="$EXTRA_DANGERFILE" \ + -e "$EXTRA_DANGERFILE" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" From 49e1cb3d7f014cef4a069df4d6d7f52ea379e809 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 21 Oct 2025 16:50:24 +0100 Subject: [PATCH 12/19] missing dangerfile input definition --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 4d9ac72..61e5e29 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -70,7 +70,7 @@ runs: -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ -e "$GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - -e "$EXTRA_DANGERFILE" \ + -e "$EXTRA_DANGERFILE_INPUT" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" From f2dfd1a5e5cf3326572a464dfebc9f36c8ef9e4d Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 21 Oct 2025 16:55:45 +0100 Subject: [PATCH 13/19] fix empty EXTRA_DANGERFILE_INPUT --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 61e5e29..55a513d 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -70,7 +70,7 @@ runs: -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ -e "$GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - -e "$EXTRA_DANGERFILE_INPUT" \ + -e "EXTRA_DANGERFILE_INPUT=$EXTRA_DANGERFILE_INPUT" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" From 0a9ab787ce6c2efd12aa3707916787d127a89899 Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 21 Oct 2025 17:00:32 +0100 Subject: [PATCH 14/19] fix env name --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 55a513d..6fc5ff6 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -68,7 +68,7 @@ runs: --workdir /github/workspace \ --user $(id -u) \ -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ - -e "$GITHUB_TOKEN" \ + -e GITHUB_TOKEN="$GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ -e "EXTRA_DANGERFILE_INPUT=$EXTRA_DANGERFILE_INPUT" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ From 3b579514df1e11f1da6ec52c138f4cfa8758006d Mon Sep 17 00:00:00 2001 From: lucas Date: Tue, 21 Oct 2025 17:12:44 +0100 Subject: [PATCH 15/19] applied code suggestions --- danger/dangerfile.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/danger/dangerfile.js b/danger/dangerfile.js index ac6b471..990322b 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -194,13 +194,17 @@ async function checkFromExternalChecks() { if (extraDangerFilePath) { try { const workspaceDir = '/github/workspace'; - const customPath = `${workspaceDir}/${extraDangerFilePath}`; - if (extraDangerFilePath.indexOf('..') !== -1) { - fail(`Invalid dangerfile path: ${customPath}. Path traversal is not allowed.`); + const path = require('path'); + const fs = require('fs'); + const customPath = path.join(workspaceDir, extraDangerFilePath); + // Ensure the resolved path is within workspace + const resolvedPath = fs.realpathSync(customPath); + if (!resolvedPath.startsWith(workspaceDir)) { + fail(`Invalid dangerfile path: ${extraDangerFilePath}. Must be within workspace.`); return; } - + const extraModule = require(customPath); if (typeof extraModule !== 'function') { warn(`EXTRA_DANGERFILE must export a function at ${customPath}`); From 5a3a11d017e5b40fe2be5bad715170a39ccba847 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos <6349682+vaind@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:22:59 +0100 Subject: [PATCH 16/19] Apply suggestion from @vaind --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 6fc5ff6..5947d7b 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -70,7 +70,7 @@ runs: -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ -e GITHUB_TOKEN="$GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ - -e "EXTRA_DANGERFILE_INPUT=$EXTRA_DANGERFILE_INPUT" \ + -e "EXTRA_DANGERFILE_INPUT" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ -c "sleep infinity" From 5be56142f6ab11933aeee40c284b1c4185c2aa69 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos <6349682+vaind@users.noreply.github.com> Date: Wed, 29 Oct 2025 09:23:09 +0100 Subject: [PATCH 17/19] Apply suggestion from @vaind --- danger/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/danger/action.yml b/danger/action.yml index 5947d7b..17554c7 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -68,7 +68,7 @@ runs: --workdir /github/workspace \ --user $(id -u) \ -e "INPUT_ARGS" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -e CI=true \ - -e GITHUB_TOKEN="$GITHUB_TOKEN" \ + -e "GITHUB_TOKEN" \ -e DANGER_DISABLE_TRANSPILATION="true" \ -e "EXTRA_DANGERFILE_INPUT" \ ghcr.io/danger/danger-js:${{ steps.config.outputs.version }} \ From 240ed218c2426db05ed7087d94717312f59fa408 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Wed, 29 Oct 2025 09:43:15 +0100 Subject: [PATCH 18/19] chore: minor refactoring --- danger/README.md | 2 +- danger/action.yml | 28 +++++++++++++++++----------- danger/dangerfile.js | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/danger/README.md b/danger/README.md index 482f2a1..e979ab4 100644 --- a/danger/README.md +++ b/danger/README.md @@ -76,4 +76,4 @@ module.exports = async function ({ fail, warn, message, markdown, danger }) { warn('...'); } -``` \ No newline at end of file +``` diff --git a/danger/action.yml b/danger/action.yml index 17554c7..3148668 100644 --- a/danger/action.yml +++ b/danger/action.yml @@ -26,10 +26,8 @@ runs: steps: - name: Checkout repository uses: actions/checkout@v4 - env: - API_TOKEN: ${{ inputs.api-token }} with: - token: ${{ env.API_TOKEN }} + token: ${{ inputs.api-token }} fetch-depth: 0 # Read the Danger version from the properties file @@ -41,16 +39,19 @@ runs: # Validate extra-install-packages to prevent code injection - name: Validate package names if: ${{ inputs.extra-install-packages }} - shell: bash + shell: pwsh env: EXTRA_INSTALL_PACKAGES: ${{ inputs.extra-install-packages }} run: | - packages="$EXTRA_INSTALL_PACKAGES" - # Only allow alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces - if ! echo "$packages" | grep -E '^[a-zA-Z0-9._+-]+( [a-zA-Z0-9._+-]+)*$' > /dev/null; then - echo "::error::Invalid package names in extra-install-packages. Only alphanumeric characters, hyphens, periods, plus signs, underscores, and spaces are allowed." - exit 1 - fi + # Validate against Debian package naming rules: must start with alphanumeric, + # contain only lowercase letters, digits, hyphens, plus signs, periods + # Package names cannot start with hyphen or period, and must be reasonable length + foreach ($pkg in $env:EXTRA_INSTALL_PACKAGES -split '\s+') { + if ($pkg -notmatch '^[a-z0-9][a-z0-9.+-]{0,100}$') { + Write-Host "::error::Invalid package name '$pkg'. Debian packages must start with lowercase letter or digit and contain only lowercase letters, digits, hyphens, periods, and plus signs." + exit 1 + } + } # Using a pre-built docker image in GitHub container registry instead of NPM to reduce possible attack vectors. - name: Setup container @@ -88,4 +89,9 @@ runs: id: danger shell: bash run: | - docker exec --user $(id -u) danger danger ci --fail-on-errors --dangerfile ${{ github.action_path }}/dangerfile.js \ No newline at end of file + docker exec --user $(id -u) danger danger ci --fail-on-errors --dangerfile ${{ github.action_path }}/dangerfile.js + + - name: Cleanup container + if: always() + shell: bash + run: docker rm -f danger || true diff --git a/danger/dangerfile.js b/danger/dangerfile.js index 990322b..d5feaa4 100644 --- a/danger/dangerfile.js +++ b/danger/dangerfile.js @@ -202,7 +202,7 @@ async function checkFromExternalChecks() { const resolvedPath = fs.realpathSync(customPath); if (!resolvedPath.startsWith(workspaceDir)) { fail(`Invalid dangerfile path: ${extraDangerFilePath}. Must be within workspace.`); - return; + throw new Error('Security violation: dangerfile path outside workspace'); } const extraModule = require(customPath); From 35ba3350b3e3416811b9c7f654ac6a56e638bab7 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Wed, 29 Oct 2025 09:48:32 +0100 Subject: [PATCH 19/19] test(danger): Add comprehensive tests for extra-dangerfile and extra-install-packages features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test coverage for the new extra-dangerfile and extra-install-packages inputs: - Create test-dangerfile.js demonstrating custom Danger checks - Add extra-dangerfile-test job to verify custom dangerfiles execute correctly - Add extra-packages-test job to verify package installation works - Tests validate that custom dangerfiles can access the Danger API and installed packages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/test-dangerfile.js | 37 ++++++++++++ .github/workflows/danger-workflow-tests.yml | 67 +++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 .github/test-dangerfile.js diff --git a/.github/test-dangerfile.js b/.github/test-dangerfile.js new file mode 100644 index 0000000..b125452 --- /dev/null +++ b/.github/test-dangerfile.js @@ -0,0 +1,37 @@ +// Test dangerfile for exercising extra-dangerfile feature +// This demonstrates how repositories can add custom Danger checks + +module.exports = async function ({ fail, warn, message, markdown, danger }) { + console.log('::notice::Running custom dangerfile checks...'); + + // Test that we have access to the danger API + if (!danger || !danger.github || !danger.github.pr) { + fail('Custom dangerfile cannot access danger API'); + return; + } + + // Example check: Verify PR has a description + const prBody = danger.github.pr.body; + if (!prBody || prBody.trim().length === 0) { + warn('PR description is empty. Consider adding a description to help reviewers.'); + } else { + message('✅ Custom dangerfile check: PR has a description'); + } + + // Example check: Verify PR title is not too short + const prTitle = danger.github.pr.title; + if (prTitle && prTitle.length < 10) { + warn('PR title is quite short. Consider making it more descriptive.'); + } else { + message('✅ Custom dangerfile check: PR title length is reasonable'); + } + + // Show that we can access git information + const modifiedFiles = danger.git.modified_files || []; + const createdFiles = danger.git.created_files || []; + const totalChangedFiles = modifiedFiles.length + createdFiles.length; + + message(`📊 Custom check: This PR changes ${totalChangedFiles} file(s)`); + + console.log('::notice::Custom dangerfile checks completed successfully'); +}; diff --git a/.github/workflows/danger-workflow-tests.yml b/.github/workflows/danger-workflow-tests.yml index 3d1b14e..bd24ebb 100644 --- a/.github/workflows/danger-workflow-tests.yml +++ b/.github/workflows/danger-workflow-tests.yml @@ -34,3 +34,70 @@ jobs: Write-Host "✅ Danger PR analysis completed successfully!" Write-Host "â„šī¸ Check the PR comments for any Danger findings" + + # Test extra-dangerfile feature + extra-dangerfile-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Run danger with extra dangerfile + id: danger-extra + uses: ./danger + with: + extra-dangerfile: '.github/test-dangerfile.js' + + - name: Validate danger with extra-dangerfile outputs + env: + DANGER_OUTCOME: ${{ steps.danger-extra.outputs.outcome }} + shell: pwsh + run: | + Write-Host "🔍 Validating Danger action with extra-dangerfile..." + Write-Host "Danger Outcome: '$env:DANGER_OUTCOME'" + + # Validate that Danger ran successfully + $env:DANGER_OUTCOME | Should -Be "success" + + Write-Host "✅ Danger with extra-dangerfile completed successfully!" + + # Test extra-install-packages feature + extra-packages-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # Create a test dangerfile that requires curl + - name: Create test dangerfile requiring curl + shell: bash + run: | + cat > .github/test-dangerfile-curl.js << 'EOF' + module.exports = async function ({ message, danger }) { + const { execSync } = require('child_process'); + try { + const curlVersion = execSync('curl --version', { encoding: 'utf-8' }); + message('✅ curl is available: ' + curlVersion.split('\n')[0]); + } catch (err) { + throw new Error('curl command not found - extra-install-packages failed'); + } + }; + EOF + + - name: Run danger with extra packages + id: danger-packages + uses: ./danger + with: + extra-dangerfile: '.github/test-dangerfile-curl.js' + extra-install-packages: 'curl' + + - name: Validate danger with extra-install-packages outputs + env: + DANGER_OUTCOME: ${{ steps.danger-packages.outputs.outcome }} + shell: pwsh + run: | + Write-Host "🔍 Validating Danger action with extra-install-packages..." + Write-Host "Danger Outcome: '$env:DANGER_OUTCOME'" + + # Validate that Danger ran successfully + $env:DANGER_OUTCOME | Should -Be "success" + + Write-Host "✅ Danger with extra-install-packages completed successfully!"