diff --git a/.github/workflows/build-publish-image.yml b/.github/workflows/build-publish-image.yml new file mode 100644 index 00000000..d8939e70 --- /dev/null +++ b/.github/workflows/build-publish-image.yml @@ -0,0 +1,63 @@ +name: Build and Publish Bandit Images + +on: + release: + types: [created] + schedule: + - cron: '0 0 * * 0' # Every Sunday at midnight + workflow_dispatch: + +jobs: + build-and-publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + + - name: Get latest release tag + if: github.event_name != 'release' + id: get-latest-tag + run: | + TAG=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) + echo "Latest tag is $TAG" + echo "RELEASE_TAG=$TAG" >> $GITHUB_ENV + + - name: Check out the repo + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + with: + ref: ${{ github.event_name == 'release' && github.ref || env.RELEASE_TAG }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Cosign + uses: sigstore/cosign-installer@9614fae9e5c5eddabb09f90a270fcb487c9f7149 # v3.3.0 + with: + cosign-release: 'v2.2.2' + + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: ghcr.io/${{ github.repository }}/bandit:latest + platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v8 + + - name: Sign the image + env: + TAGS: ghcr.io/${{ github.repository }}/bandit:latest + DIGEST: ${{ steps.build-and-push.outputs.digest }} + run: | + echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} diff --git a/README.rst b/README.rst index e32f8fd7..a06f90c9 100644 --- a/README.rst +++ b/README.rst @@ -83,3 +83,37 @@ https://greentreesnakes.readthedocs.org/en/latest/ Documentation of the various types of AST nodes that Bandit currently covers or could be extended to cover: https://greentreesnakes.readthedocs.org/en/latest/nodes.html + +Container Images +---------------- + +Bandit is available as a container image, built within the bandit repository +using GitHub Actions. The image is available on ghcr.io: + +```bash +docker pull ghcr.io/pycqa/bandit/bandit +``` + +The image is built for the following architectures: + +* amd64 +* arm64 +* armv7 +* armv8 + +To pull a specific architecture, use the following format: + +```bash +docker pull --platform= ghcr.io/pycqa/bandit/bandit:latest +``` + +Every image is signed with sigstore cosign and it is possible to verify the +source of origin using the following cosign command: + +```bash +cosign verify ghcr.io/pycqa/bandit/bandit:py39-amd64 \ + --certificate-identity https://github.com/pycqa/bandit/.github/workflows/build-publish-image.yml@refs/tags/ \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com +``` + +Where `` is the release version of Bandit. diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..ab33e870 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.12-alpine + +# Install Git (required for pbr versioning) +RUN apk add --no-cache git + +# Copy the source code into the container +COPY . /bandit + +# Set the working directory +WORKDIR /bandit + +# Install Bandit from the source code using pip +RUN pip install . + +# Define entrypoint and default command +ENTRYPOINT ["bandit"]