secureCodeBox/secureCodeBox

View on GitHub
.github/workflows/scb-bot.yaml

Summary

Maintainability
Test Coverage
# SPDX-FileCopyrightText: the secureCodeBox authors
#
# SPDX-License-Identifier: Apache-2.0

# This is a Github Action workflow that runs daily at 9:15 AM UTC Time.
# It checks if any of the scanners listed in the matrix section are outdated.
# If a scanner is outdated, it checks if a pull request to upgrade that scanner already exists.
# If it does not, it creates a new pull request with a title that includes the current and new versions of the scanner.
# It also includes the changelog for the new version of the scanner in the body of the pull request.
# This workflow uses a number of third-party actions to accomplish these tasks,
# including mikefarah/yq to fetch local and remote versions of the scanners,
# crazy-max/ghaction-import-gpg to import a GPG key, and jq to parse the JSON output of the scanner version API.


# The CI runs on ubuntu-22.04; More info about the installed software is found here:
# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md

name: Check outdated scanners
on:
  schedule:
    - cron: "15 9 * * *" # Daily at 9:15 (avoids the beginning of the hour congestion)
jobs:
  version-compare:
    runs-on: ubuntu-22.04
    if: github.repository == 'secureCodeBox/secureCodeBox'
    strategy:
      # Keep running other jobs even if one fails
      fail-fast: false
      matrix:
        scanner:
          - amass
          - cmseek
          - doggo
          - ffuf
          - gitleaks
          - kube-hunter
          - kubeaudit
          - ncrack
          - nuclei
          - semgrep
          - ssh-audit
          - ssh-scan
          - sslyze
          - trivy
          - trivy-sbom
          - typo3scan
          - whatweb
          - wpscan
          - zap
          - zap-advanced
          # missing scanners are : nmap, nikto
    steps:
      - uses: actions/checkout@v4

      - name: Import GPG key
        uses: crazy-max/ghaction-import-gpg@v6
        with:
          gpg_private_key: ${{ secrets.GPG_COMMITS_PRIVATE_KEY }}
          passphrase: ${{ secrets.GPG_COMMITS_PASSPHRASE }}
          git_user_signingkey: true
          git_commit_gpgsign: true

      # Fetching scanner version from local chart .appVersion attribute
      # this would look like 1.1.1 or v1.1.1 depending on the corresponding Docker image tag
      - name: Fetch local scanner version
        uses: mikefarah/yq@v4.43.1
        with:
          cmd: echo local=$(yq e .appVersion scanners/${{ matrix.scanner }}/Chart.yaml) >> $GITHUB_ENV

      # Fetching scanner version API from local chart .annotations.versionApi attribute
      # This would look like https://api.github.com/repos/OWASP/Amass/releases/latest
      - name: Fetch scanner's version API
        uses: mikefarah/yq@v4.43.1
        with:
          cmd: echo versionApi=$(yq e .annotations.versionApi scanners/${{ matrix.scanner }}/Chart.yaml) >> $GITHUB_ENV

      # Fetching scanner version from remote API and making sure it's in the same format as the local version
      - name: Fetch latest release scanner version
        run: |
          # Set the -e and -o pipefail options to cause the script to exit immediately
          # if any command returns a non-zero exit status
          set -e
          set -o pipefail

          local=${{env.local}}
          release=$(curl -sL ${{env.versionApi}}  | jq -er ".tag_name" ) 
          upgrade=$release

          # Check the exit status of the curl and jq command
          if [[ $? -ne 0 ]] ; then
            echo "Error: Failed to download release version"
            exit 1
          fi

          # We check if the first characters of local and release are different i.e whether it's "v1.0.0" or "1.0.0"
          # This is to make sure that we don't compare "v1.0.0" to "1.0.0" which would result in an upgrade
          # And also we want to keep the version format the same in the helm chart so that it will still correspond the the docker image tag.
          # Therefore We make sure to add or remove the "v" character when necessary

          if [[ ${local:0:1} != ${release:0:1} ]] ; then
            # Check if the first character of local is "v"
            # In this case docker/local format is "v1.0.0" and github format is "1.0.1"
            # We want the upgrade to be "v1.0.1" 
            if [[ ${local:0:1} == "v" ]] ; then
              # set upgrade to "v" followed by the value of release.
              upgrade=v${release};
            # Check if the first character of release is "v"  
            # in this case docker/local format is "1.0.0" and github format is "v1.0.1"
            # We want the upgrade to be "1.0.1"
            elif [[ ${release:0:1} == "v" ]] ; then
              # set upgrade to the value of release without the "v" character
              upgrade=$(echo $release| tr -d "v")
            fi
          fi


          # Save how the latest release version looks in github releases to an environment variable
          echo releaseGithub=$release >> $GITHUB_ENV
          # Save how the latest release version looks in docker images to an environment variable
          echo release=$upgrade >> $GITHUB_ENV
          # Output bash exit code
          echo exitCode=$?

      - name: Check if scanner is outdated and if PR already exists
        if: ${{ env.release != env.local && env.release != null }}
        run: |
          echo 'The ${{ matrix.scanner }} scanner is outdated.  Current SCB version is ${{env.local}} and remote version is ${{env.release}}'

          pullRequestTitle="[SCB-Bot] Upgraded ${{ matrix.scanner }} from ${{env.local}} to ${{env.release}}"
          echo pullRequest=$pullRequestTitle >> $GITHUB_ENV

          echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
          echo prExists=$(gh pr list --state all --limit 100 | grep -F "$pullRequestTitle" -c) >> $GITHUB_ENV

      - name: Fetch new release changelog
        if: ${{ env.release != env.local && env.release != null }}
        # Reformats the versionApi to have an HTML view of the release changelog
        # sed command is divided into three parts s/api.//g; , s/\/repos//g; and s/latest//g
        # "api." and "/repos" and "latest" are replaced with nothing (a.k.a removed)
        # example: https://api.github.com/repos/OWASP/Amass/releases/latest --> https://github.com/OWASP/Amass/releases/
        # the next command then appends the link  with the new release version as it is in Github.
        run: |
          changelog=$(echo ${{env.versionApi}} | sed -e 's/api.//g;s/\/repos//g;s/latest//g')
          echo releaseChangelog=${changelog}${{env.releaseGithub}} >> $GITHUB_ENV

      - name: Upgrade Scanner Helm Chart
        if: ${{ env.release != env.local && env.prExists == 0 && env.release != null}}
        uses: mikefarah/yq@v4.43.1
        with:
          # appVersion value in chart is replaced with release value. Empty lines are deleted in the process
          cmd: yq e --inplace '.appVersion = "${{env.release}}"' ./scanners/${{ matrix.scanner }}/Chart.yaml

      # Updating Helm Docs
      - name: Download Helm Docs
        run: |
          mkdir helm-docs
          cd helm-docs

          curl --output helm-docs.tar.gz --location https://github.com/norwoodj/helm-docs/releases/download/v1.6.0/helm-docs_1.6.0_Linux_x86_64.tar.gz
          # Checksum must be extracted from the checksum file every time helm-docs gets updated.
          echo "286723d931c18581fc324985cb96e9cce639e521fa63b57ac04ebe9d497e60fb  helm-docs.tar.gz" | shasum --check

          tar -xvf helm-docs.tar.gz
          # Verify installation
          ./helm-docs --version

          sudo mv helm-docs /usr/local/bin/helm-docs

      - name: Generate README
        run: make readme

      - name: Generate Demo Target Docs
        run: make demo-target-docs

      - name: Generate Hooks Docs
        run: make hook-docs

      - name: Generate Scanner Docs
        run: make scanner-docs

      - name: Generate Operator Docs
        run: make operator-docs

      - name: Generate AutoDiscovery Docs
        run: make auto-discovery-docs

      - name: Remove Helm Docs Files
        run: |
          # Remove helm-docs download to ensure they don't get committed back
          rm -rf helm-docs

      - name: Create Pull Request
        if: ${{ env.release != env.local && env.prExists == 0 && env.release != null }}
        uses: peter-evans/create-pull-request@v6
        with:
          token: ${{ secrets.SCB_BOT_USER_TOKEN }}
          committer: secureCodeBoxBot <securecodebox@iteratec.com>
          author: secureCodeBoxBot <securecodebox@iteratec.com>
          title: ${{ env.pullRequest }}
          body: |
            This is an automated Pull Request by the SCB-Bot. It upgrades ${{ matrix.scanner }} from ${{env.local}} to ${{env.release}}
            ### Release changes : [here](${{env.releaseChangelog}})
          branch: "dependencies/upgrading-${{ matrix.scanner }}-to-${{env.release}}"
          labels: scanner
          commit-message: "Upgrading ${{ matrix.scanner }} from ${{env.local}} to ${{env.release}}"
          signoff: true
          base: main