From 682d4601e9da24f33c743e5d7851c98d25badc18 Mon Sep 17 00:00:00 2001 From: noqt Date: Thu, 27 Aug 2026 16:46:21 +1000 Subject: [PATCH 1/2] Preserve Bandit execution errors Allow Bandit exit 0 and 1 to continue to SARIF upload, but stop on execution errors so the original failure stays visible. --- action.yml | 305 +++++++++++++++++++++++++++-------------------------- 1 file changed, 158 insertions(+), 147 deletions(-) diff --git a/action.yml b/action.yml index af9b950..16fad1a 100644 --- a/action.yml +++ b/action.yml @@ -1,149 +1,160 @@ -name: Bandit by PyCQA -description: The official Bandit Action developed by PyCQA -author: '@PyCQA' +name: Bandit by PyCQA +description: The official Bandit Action developed by PyCQA +author: '@PyCQA' + +branding: + icon: 'shield' + color: 'black' + +inputs: + python-version: + description: | + Version of Python to use + required: false + default: '3.9' + configfile: + description: | + Optional config file to use for selecting plugins and overriding defaults + required: false + default: 'DEFAULT' + profile: + description: | + Profile to use (defaults to executing all tests) + required: false + default: 'DEFAULT' + tests: + description: | + Comma-separated list of test IDs to run + required: false + default: 'DEFAULT' + skips: + description: | + Comma-separated list of test IDs to skip + required: false + default: 'DEFAULT' + severity: + description: | + Report only issues of a given severity level or higher. "all" and "low" + are likely to produce the same results, but it is possible for rules to + be undefined which will not be listed in "low". Options include: + {all, high, medium, low} + required: false + default: 'DEFAULT' + confidence: + description: | + Report only issues of a given confidence level or higher. "all" and "low" + are likely to produce the same results, but it is possible for rules to + be undefined which will not be listed in "low". Options include: + {all, high, medium, low} + required: false + default: 'DEFAULT' + exclude: + description: | + Comma-separated list of paths (glob patterns supported) to exclude from + scan (note that these are in addition to the excluded paths provided in + the config file) + required: false + default: '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg' + baseline: + description: | + Path of a baseline report to compare against (only JSON-formatted files + are accepted) + required: false + default: 'DEFAULT' + ini: + description: | + Path to a .bandit file that supplies command line arguments + required: false + default: 'DEFAULT' + targets: + description: | + Source file(s) or directory(s) to be tested + required: true + default: '.' + +runs: + using: composite + steps: + - name: Set up Python ${{ inputs.python-version }} + uses: actions/setup-python@v7 + with: + python-version: ${{ inputs.python-version }} + + - name: Install Bandit + shell: bash + run: pip install bandit[sarif,toml] + + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Run Bandit + shell: bash + run: | + if [ "$INPUT_CONFIGFILE" == "DEFAULT" ]; then + CONFIGFILE="" + else + CONFIGFILE="-c $INPUT_CONFIGFILE" + fi + if [ "$INPUT_PROFILE" == "DEFAULT" ]; then + PROFILE="" + else + PROFILE="-p $INPUT_PROFILE" + fi + if [ "$INPUT_TESTS" == "DEFAULT" ]; then + TESTS="" + else + TESTS="-t $INPUT_TESTS" + fi + if [ "$INPUT_SKIPS" == "DEFAULT" ]; then + SKIPS="" + else + SKIPS="-s $INPUT_SKIPS" + fi + if [ "$INPUT_SEVERITY" == "DEFAULT" ]; then + SEVERITY="" + else + SEVERITY="--severity-level $INPUT_SEVERITY" + fi + if [ "$INPUT_CONFIDENCE" == "DEFAULT" ]; then + CONFIDENCE="" + else + CONFIDENCE="--confidence-level $INPUT_CONFIDENCE" + fi + if [ "$INPUT_BASELINE" == "DEFAULT" ]; then + BASELINE="" + else + BASELINE="-b $INPUT_BASELINE" + fi + if [ "$INPUT_INI" == "DEFAULT" ]; then + INI="" + else + INI="--ini $INPUT_INI" + fi + set +e + bandit $CONFIGFILE $PROFILE $TESTS $SKIPS $SEVERITY $CONFIDENCE -x $INPUT_EXCLUDE $BASELINE $INI -r $INPUT_TARGETS -f sarif -o results.sarif + BANDIT_EXIT_CODE=$? + set -e -branding: - icon: 'shield' - color: 'black' - -inputs: - python-version: - description: | - Version of Python to use - required: false - default: '3.9' - configfile: - description: | - Optional config file to use for selecting plugins and overriding defaults - required: false - default: 'DEFAULT' - profile: - description: | - Profile to use (defaults to executing all tests) - required: false - default: 'DEFAULT' - tests: - description: | - Comma-separated list of test IDs to run - required: false - default: 'DEFAULT' - skips: - description: | - Comma-separated list of test IDs to skip - required: false - default: 'DEFAULT' - severity: - description: | - Report only issues of a given severity level or higher. "all" and "low" - are likely to produce the same results, but it is possible for rules to - be undefined which will not be listed in "low". Options include: - {all, high, medium, low} - required: false - default: 'DEFAULT' - confidence: - description: | - Report only issues of a given confidence level or higher. "all" and "low" - are likely to produce the same results, but it is possible for rules to - be undefined which will not be listed in "low". Options include: - {all, high, medium, low} - required: false - default: 'DEFAULT' - exclude: - description: | - Comma-separated list of paths (glob patterns supported) to exclude from - scan (note that these are in addition to the excluded paths provided in - the config file) - required: false - default: '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg' - baseline: - description: | - Path of a baseline report to compare against (only JSON-formatted files - are accepted) - required: false - default: 'DEFAULT' - ini: - description: | - Path to a .bandit file that supplies command line arguments - required: false - default: 'DEFAULT' - targets: - description: | - Source file(s) or directory(s) to be tested - required: true - default: '.' - -runs: - using: composite - steps: - - name: Set up Python ${{ inputs.python-version }} - uses: actions/setup-python@v7 - with: - python-version: ${{ inputs.python-version }} - - - name: Install Bandit - shell: bash - run: pip install bandit[sarif,toml] - - - name: Checkout repository - uses: actions/checkout@v7 - - - name: Run Bandit - shell: bash - run: | - if [ "$INPUT_CONFIGFILE" == "DEFAULT" ]; then - CONFIGFILE="" - else - CONFIGFILE="-c $INPUT_CONFIGFILE" - fi - if [ "$INPUT_PROFILE" == "DEFAULT" ]; then - PROFILE="" - else - PROFILE="-p $INPUT_PROFILE" - fi - if [ "$INPUT_TESTS" == "DEFAULT" ]; then - TESTS="" - else - TESTS="-t $INPUT_TESTS" + # Bandit returns 1 when it finds issues and still writes valid SARIF. + # Higher exit codes are execution errors; stop before upload-sarif can + # replace Bandit's useful error with a secondary JSON parse failure. + if [ "$BANDIT_EXIT_CODE" -gt 1 ]; then + echo "::error::Bandit failed with exit code $BANDIT_EXIT_CODE" + exit "$BANDIT_EXIT_CODE" fi - if [ "$INPUT_SKIPS" == "DEFAULT" ]; then - SKIPS="" - else - SKIPS="-s $INPUT_SKIPS" - fi - if [ "$INPUT_SEVERITY" == "DEFAULT" ]; then - SEVERITY="" - else - SEVERITY="--severity-level $INPUT_SEVERITY" - fi - if [ "$INPUT_CONFIDENCE" == "DEFAULT" ]; then - CONFIDENCE="" - else - CONFIDENCE="--confidence-level $INPUT_CONFIDENCE" - fi - if [ "$INPUT_BASELINE" == "DEFAULT" ]; then - BASELINE="" - else - BASELINE="-b $INPUT_BASELINE" - fi - if [ "$INPUT_INI" == "DEFAULT" ]; then - INI="" - else - INI="--ini $INPUT_INI" - fi - bandit $CONFIGFILE $PROFILE $TESTS $SKIPS $SEVERITY $CONFIDENCE -x $INPUT_EXCLUDE $BASELINE $INI -r $INPUT_TARGETS -f sarif -o results.sarif || true - env: - INPUT_CONFIGFILE: ${{ inputs.configfile }} - INPUT_PROFILE: ${{ inputs.profile }} - INPUT_TESTS: ${{ inputs.tests }} - INPUT_SKIPS: ${{ inputs.skips }} - INPUT_SEVERITY: ${{ inputs.severity }} - INPUT_CONFIDENCE: ${{ inputs.confidence }} - INPUT_EXCLUDE: ${{ inputs.exclude }} - INPUT_BASELINE: ${{ inputs.baseline }} - INPUT_INI: ${{ inputs.ini }} - INPUT_TARGETS: ${{ inputs.targets }} - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v4.37.8 - with: - sarif_file: results.sarif + env: + INPUT_CONFIGFILE: ${{ inputs.configfile }} + INPUT_PROFILE: ${{ inputs.profile }} + INPUT_TESTS: ${{ inputs.tests }} + INPUT_SKIPS: ${{ inputs.skips }} + INPUT_SEVERITY: ${{ inputs.severity }} + INPUT_CONFIDENCE: ${{ inputs.confidence }} + INPUT_EXCLUDE: ${{ inputs.exclude }} + INPUT_BASELINE: ${{ inputs.baseline }} + INPUT_INI: ${{ inputs.ini }} + INPUT_TARGETS: ${{ inputs.targets }} + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v4.37.8 + with: + sarif_file: results.sarif From ce5ed60a45cd466769b268084f5000e2f8bcf951 Mon Sep 17 00:00:00 2001 From: noqt Date: Thu, 27 Aug 2026 16:47:08 +1000 Subject: [PATCH 2/2] Normalize action file line endings Restore the upstream LF line endings so the pull request contains only the intended Bandit exit-code handling change. --- action.yml | 296 ++++++++++++++++++++++++++--------------------------- 1 file changed, 148 insertions(+), 148 deletions(-) diff --git a/action.yml b/action.yml index 16fad1a..eba8319 100644 --- a/action.yml +++ b/action.yml @@ -1,135 +1,135 @@ -name: Bandit by PyCQA -description: The official Bandit Action developed by PyCQA -author: '@PyCQA' - -branding: - icon: 'shield' - color: 'black' - -inputs: - python-version: - description: | - Version of Python to use - required: false - default: '3.9' - configfile: - description: | - Optional config file to use for selecting plugins and overriding defaults - required: false - default: 'DEFAULT' - profile: - description: | - Profile to use (defaults to executing all tests) - required: false - default: 'DEFAULT' - tests: - description: | - Comma-separated list of test IDs to run - required: false - default: 'DEFAULT' - skips: - description: | - Comma-separated list of test IDs to skip - required: false - default: 'DEFAULT' - severity: - description: | - Report only issues of a given severity level or higher. "all" and "low" - are likely to produce the same results, but it is possible for rules to - be undefined which will not be listed in "low". Options include: - {all, high, medium, low} - required: false - default: 'DEFAULT' - confidence: - description: | - Report only issues of a given confidence level or higher. "all" and "low" - are likely to produce the same results, but it is possible for rules to - be undefined which will not be listed in "low". Options include: - {all, high, medium, low} - required: false - default: 'DEFAULT' - exclude: - description: | - Comma-separated list of paths (glob patterns supported) to exclude from - scan (note that these are in addition to the excluded paths provided in - the config file) - required: false - default: '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg' - baseline: - description: | - Path of a baseline report to compare against (only JSON-formatted files - are accepted) - required: false - default: 'DEFAULT' - ini: - description: | - Path to a .bandit file that supplies command line arguments - required: false - default: 'DEFAULT' - targets: - description: | - Source file(s) or directory(s) to be tested - required: true - default: '.' - -runs: - using: composite - steps: - - name: Set up Python ${{ inputs.python-version }} - uses: actions/setup-python@v7 - with: - python-version: ${{ inputs.python-version }} - - - name: Install Bandit - shell: bash - run: pip install bandit[sarif,toml] - - - name: Checkout repository - uses: actions/checkout@v7 - - - name: Run Bandit - shell: bash - run: | - if [ "$INPUT_CONFIGFILE" == "DEFAULT" ]; then - CONFIGFILE="" - else - CONFIGFILE="-c $INPUT_CONFIGFILE" - fi - if [ "$INPUT_PROFILE" == "DEFAULT" ]; then - PROFILE="" - else - PROFILE="-p $INPUT_PROFILE" - fi - if [ "$INPUT_TESTS" == "DEFAULT" ]; then - TESTS="" - else - TESTS="-t $INPUT_TESTS" - fi - if [ "$INPUT_SKIPS" == "DEFAULT" ]; then - SKIPS="" - else - SKIPS="-s $INPUT_SKIPS" - fi - if [ "$INPUT_SEVERITY" == "DEFAULT" ]; then - SEVERITY="" - else - SEVERITY="--severity-level $INPUT_SEVERITY" - fi - if [ "$INPUT_CONFIDENCE" == "DEFAULT" ]; then - CONFIDENCE="" - else - CONFIDENCE="--confidence-level $INPUT_CONFIDENCE" - fi - if [ "$INPUT_BASELINE" == "DEFAULT" ]; then - BASELINE="" - else - BASELINE="-b $INPUT_BASELINE" - fi - if [ "$INPUT_INI" == "DEFAULT" ]; then - INI="" - else - INI="--ini $INPUT_INI" - fi +name: Bandit by PyCQA +description: The official Bandit Action developed by PyCQA +author: '@PyCQA' + +branding: + icon: 'shield' + color: 'black' + +inputs: + python-version: + description: | + Version of Python to use + required: false + default: '3.9' + configfile: + description: | + Optional config file to use for selecting plugins and overriding defaults + required: false + default: 'DEFAULT' + profile: + description: | + Profile to use (defaults to executing all tests) + required: false + default: 'DEFAULT' + tests: + description: | + Comma-separated list of test IDs to run + required: false + default: 'DEFAULT' + skips: + description: | + Comma-separated list of test IDs to skip + required: false + default: 'DEFAULT' + severity: + description: | + Report only issues of a given severity level or higher. "all" and "low" + are likely to produce the same results, but it is possible for rules to + be undefined which will not be listed in "low". Options include: + {all, high, medium, low} + required: false + default: 'DEFAULT' + confidence: + description: | + Report only issues of a given confidence level or higher. "all" and "low" + are likely to produce the same results, but it is possible for rules to + be undefined which will not be listed in "low". Options include: + {all, high, medium, low} + required: false + default: 'DEFAULT' + exclude: + description: | + Comma-separated list of paths (glob patterns supported) to exclude from + scan (note that these are in addition to the excluded paths provided in + the config file) + required: false + default: '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg' + baseline: + description: | + Path of a baseline report to compare against (only JSON-formatted files + are accepted) + required: false + default: 'DEFAULT' + ini: + description: | + Path to a .bandit file that supplies command line arguments + required: false + default: 'DEFAULT' + targets: + description: | + Source file(s) or directory(s) to be tested + required: true + default: '.' + +runs: + using: composite + steps: + - name: Set up Python ${{ inputs.python-version }} + uses: actions/setup-python@v7 + with: + python-version: ${{ inputs.python-version }} + + - name: Install Bandit + shell: bash + run: pip install bandit[sarif,toml] + + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Run Bandit + shell: bash + run: | + if [ "$INPUT_CONFIGFILE" == "DEFAULT" ]; then + CONFIGFILE="" + else + CONFIGFILE="-c $INPUT_CONFIGFILE" + fi + if [ "$INPUT_PROFILE" == "DEFAULT" ]; then + PROFILE="" + else + PROFILE="-p $INPUT_PROFILE" + fi + if [ "$INPUT_TESTS" == "DEFAULT" ]; then + TESTS="" + else + TESTS="-t $INPUT_TESTS" + fi + if [ "$INPUT_SKIPS" == "DEFAULT" ]; then + SKIPS="" + else + SKIPS="-s $INPUT_SKIPS" + fi + if [ "$INPUT_SEVERITY" == "DEFAULT" ]; then + SEVERITY="" + else + SEVERITY="--severity-level $INPUT_SEVERITY" + fi + if [ "$INPUT_CONFIDENCE" == "DEFAULT" ]; then + CONFIDENCE="" + else + CONFIDENCE="--confidence-level $INPUT_CONFIDENCE" + fi + if [ "$INPUT_BASELINE" == "DEFAULT" ]; then + BASELINE="" + else + BASELINE="-b $INPUT_BASELINE" + fi + if [ "$INPUT_INI" == "DEFAULT" ]; then + INI="" + else + INI="--ini $INPUT_INI" + fi set +e bandit $CONFIGFILE $PROFILE $TESTS $SKIPS $SEVERITY $CONFIDENCE -x $INPUT_EXCLUDE $BASELINE $INI -r $INPUT_TARGETS -f sarif -o results.sarif BANDIT_EXIT_CODE=$? @@ -142,19 +142,19 @@ runs: echo "::error::Bandit failed with exit code $BANDIT_EXIT_CODE" exit "$BANDIT_EXIT_CODE" fi - env: - INPUT_CONFIGFILE: ${{ inputs.configfile }} - INPUT_PROFILE: ${{ inputs.profile }} - INPUT_TESTS: ${{ inputs.tests }} - INPUT_SKIPS: ${{ inputs.skips }} - INPUT_SEVERITY: ${{ inputs.severity }} - INPUT_CONFIDENCE: ${{ inputs.confidence }} - INPUT_EXCLUDE: ${{ inputs.exclude }} - INPUT_BASELINE: ${{ inputs.baseline }} - INPUT_INI: ${{ inputs.ini }} - INPUT_TARGETS: ${{ inputs.targets }} - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v4.37.8 - with: - sarif_file: results.sarif + env: + INPUT_CONFIGFILE: ${{ inputs.configfile }} + INPUT_PROFILE: ${{ inputs.profile }} + INPUT_TESTS: ${{ inputs.tests }} + INPUT_SKIPS: ${{ inputs.skips }} + INPUT_SEVERITY: ${{ inputs.severity }} + INPUT_CONFIDENCE: ${{ inputs.confidence }} + INPUT_EXCLUDE: ${{ inputs.exclude }} + INPUT_BASELINE: ${{ inputs.baseline }} + INPUT_INI: ${{ inputs.ini }} + INPUT_TARGETS: ${{ inputs.targets }} + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v4.37.8 + with: + sarif_file: results.sarif