mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-04 19:21:51 +00:00
ce80fcd430
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
369 lines
15 KiB
YAML
369 lines
15 KiB
YAML
name: 'SDK: Container Build and Push'
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- 'master'
|
|
paths-ignore:
|
|
- '.github/**'
|
|
- '!.github/workflows/sdk-container-build-push.yml'
|
|
- 'README.md'
|
|
- 'docs/**'
|
|
- 'ui/**'
|
|
- 'api/**'
|
|
release:
|
|
types:
|
|
- 'published'
|
|
workflow_dispatch:
|
|
inputs:
|
|
release_tag:
|
|
description: 'Release tag (e.g., 5.14.0)'
|
|
required: true
|
|
type: string
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
env:
|
|
# Container configuration
|
|
IMAGE_NAME: prowler
|
|
DOCKERFILE_PATH: ./Dockerfile
|
|
|
|
# Python configuration
|
|
PYTHON_VERSION: '3.12'
|
|
|
|
# Tags (dynamically set based on version)
|
|
LATEST_TAG: latest
|
|
STABLE_TAG: stable
|
|
|
|
# Container registries
|
|
PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud
|
|
PROWLERCLOUD_DOCKERHUB_IMAGE: prowler
|
|
TONIBLYX_DOCKERHUB_REPOSITORY: toniblyx
|
|
|
|
# AWS configuration (for ECR)
|
|
AWS_REGION: us-east-1
|
|
|
|
permissions: {}
|
|
|
|
jobs:
|
|
setup:
|
|
if: github.repository == 'prowler-cloud/prowler'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
prowler_version: ${{ steps.get-prowler-version.outputs.prowler_version }}
|
|
latest_tag: ${{ steps.get-prowler-version.outputs.latest_tag }}
|
|
stable_tag: ${{ steps.get-prowler-version.outputs.stable_tag }}
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
|
with:
|
|
egress-policy: block
|
|
allowed-endpoints: >
|
|
github.com:443
|
|
pypi.org:443
|
|
files.pythonhosted.org:443
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Get Prowler version and set tags
|
|
id: get-prowler-version
|
|
run: |
|
|
PROWLER_VERSION="$(grep -E '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]')"
|
|
echo "prowler_version=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}"
|
|
|
|
PROWLER_VERSION_MAJOR="${PROWLER_VERSION%%.*}"
|
|
if [[ "${PROWLER_VERSION_MAJOR}" != "5" ]]; then
|
|
echo "::error::Unsupported Prowler major version: ${PROWLER_VERSION_MAJOR}"
|
|
exit 1
|
|
fi
|
|
echo "latest_tag=latest" >> "${GITHUB_OUTPUT}"
|
|
echo "stable_tag=stable" >> "${GITHUB_OUTPUT}"
|
|
|
|
notify-release-started:
|
|
if: github.repository == 'prowler-cloud/prowler' && (github.event_name == 'release' || github.event_name == 'workflow_dispatch')
|
|
needs: setup
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
message-ts: ${{ steps.slack-notification.outputs.ts }}
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Harden the runner (Audit all outbound calls)
|
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Notify container push started
|
|
id: slack-notification
|
|
uses: ./.github/actions/slack-notification
|
|
env:
|
|
SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }}
|
|
COMPONENT: SDK
|
|
RELEASE_TAG: ${{ needs.setup.outputs.prowler_version }}
|
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
with:
|
|
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
payload-file-path: "./.github/scripts/slack-messages/container-release-started.json"
|
|
|
|
container-build-push:
|
|
needs: [setup, notify-release-started]
|
|
if: always() && needs.setup.result == 'success' && (needs.notify-release-started.result == 'success' || needs.notify-release-started.result == 'skipped')
|
|
runs-on: ${{ matrix.runner }}
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- platform: linux/amd64
|
|
runner: ubuntu-latest
|
|
arch: amd64
|
|
- platform: linux/arm64
|
|
runner: ubuntu-24.04-arm
|
|
arch: arm64
|
|
timeout-minutes: 45
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
id-token: write
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
|
with:
|
|
egress-policy: block
|
|
allowed-endpoints: >
|
|
api.ecr-public.us-east-1.amazonaws.com:443
|
|
public.ecr.aws:443
|
|
sts.amazonaws.com:443
|
|
sts.us-east-1.amazonaws.com:443
|
|
registry-1.docker.io:443
|
|
production.cloudflare.docker.com:443
|
|
production.cloudfront.docker.com:443
|
|
auth.docker.io:443
|
|
debian.map.fastlydns.net:80
|
|
github.com:443
|
|
release-assets.githubusercontent.com:443
|
|
pypi.org:443
|
|
files.pythonhosted.org:443
|
|
www.powershellgallery.com:443
|
|
aka.ms:443
|
|
cdn.powershellgallery.com:443
|
|
_http._tcp.deb.debian.org:443
|
|
powershellinfraartifacts-gkhedzdeaghdezhr.z01.azurefd.net:443
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Login to DockerHub
|
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Configure AWS credentials (OIDC)
|
|
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # v6.1.1
|
|
with:
|
|
aws-region: us-east-1
|
|
role-to-assume: ${{ secrets.PUBLIC_ECR_IAM_ROLE_ARN }}
|
|
|
|
- name: Login to Public ECR
|
|
uses: aws-actions/amazon-ecr-login@d539f0932e70871a027e9d5a9d8fc38589180a64 # v2.1.6
|
|
with:
|
|
registry-type: public
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
|
|
|
- name: Build and push SDK container for ${{ matrix.arch }}
|
|
id: container-push
|
|
if: github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'workflow_dispatch'
|
|
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
|
with:
|
|
context: .
|
|
file: ${{ env.DOCKERFILE_PATH }}
|
|
push: true
|
|
platforms: ${{ matrix.platform }}
|
|
tags: |
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ needs.setup.outputs.latest_tag }}-${{ matrix.arch }}
|
|
cache-from: type=gha,scope=${{ matrix.arch }}
|
|
cache-to: type=gha,mode=${{ github.event_name == 'pull_request' && 'min' || 'max' }},scope=${{ matrix.arch }}
|
|
|
|
# Create and push multi-architecture manifest
|
|
create-manifest:
|
|
needs: [setup, container-build-push]
|
|
if: always() && needs.setup.result == 'success' && needs.container-build-push.result == 'success'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
|
with:
|
|
egress-policy: block
|
|
allowed-endpoints: >
|
|
registry-1.docker.io:443
|
|
auth.docker.io:443
|
|
public.ecr.aws:443
|
|
production.cloudflare.docker.com:443
|
|
production.cloudfront.docker.com:443
|
|
github.com:443
|
|
release-assets.githubusercontent.com:443
|
|
api.ecr-public.us-east-1.amazonaws.com:443
|
|
sts.amazonaws.com:443
|
|
sts.us-east-1.amazonaws.com:443
|
|
|
|
|
|
- name: Login to DockerHub
|
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Configure AWS credentials (OIDC)
|
|
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # v6.1.1
|
|
with:
|
|
aws-region: us-east-1
|
|
role-to-assume: ${{ secrets.PUBLIC_ECR_IAM_ROLE_ARN }}
|
|
|
|
- name: Login to Public ECR
|
|
uses: aws-actions/amazon-ecr-login@d539f0932e70871a027e9d5a9d8fc38589180a64 # v2.1.6
|
|
with:
|
|
registry-type: public
|
|
|
|
- name: Create and push manifests for push event
|
|
if: github.event_name == 'push'
|
|
run: |
|
|
docker buildx imagetools create \
|
|
-t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG} \
|
|
-t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG} \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-amd64 \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-arm64
|
|
env:
|
|
NEEDS_SETUP_OUTPUTS_LATEST_TAG: ${{ needs.setup.outputs.latest_tag }}
|
|
|
|
- name: Create and push manifests for release event
|
|
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
|
|
run: |
|
|
docker buildx imagetools create \
|
|
-t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_PROWLER_VERSION} \
|
|
-t ${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_STABLE_TAG} \
|
|
-t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${NEEDS_SETUP_OUTPUTS_PROWLER_VERSION} \
|
|
-t ${{ secrets.PUBLIC_ECR_REPOSITORY }}/${{ env.IMAGE_NAME }}:${NEEDS_SETUP_OUTPUTS_STABLE_TAG} \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-amd64 \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-arm64
|
|
env:
|
|
NEEDS_SETUP_OUTPUTS_PROWLER_VERSION: ${{ needs.setup.outputs.prowler_version }}
|
|
NEEDS_SETUP_OUTPUTS_STABLE_TAG: ${{ needs.setup.outputs.stable_tag }}
|
|
NEEDS_SETUP_OUTPUTS_LATEST_TAG: ${{ needs.setup.outputs.latest_tag }}
|
|
|
|
# Push to toniblyx/prowler only for current version (latest/stable/release tags)
|
|
- name: Login to DockerHub (toniblyx)
|
|
if: needs.setup.outputs.latest_tag == 'latest'
|
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
|
with:
|
|
username: ${{ secrets.TONIBLYX_DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.TONIBLYX_DOCKERHUB_PASSWORD }}
|
|
|
|
- name: Push manifests to toniblyx for push event
|
|
if: needs.setup.outputs.latest_tag == 'latest' && github.event_name == 'push'
|
|
run: |
|
|
docker buildx imagetools create \
|
|
-t ${{ env.TONIBLYX_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:latest \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:latest
|
|
|
|
- name: Push manifests to toniblyx for release event
|
|
if: needs.setup.outputs.latest_tag == 'latest' && (github.event_name == 'release' || github.event_name == 'workflow_dispatch')
|
|
run: |
|
|
docker buildx imagetools create \
|
|
-t ${{ env.TONIBLYX_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_PROWLER_VERSION} \
|
|
-t ${{ env.TONIBLYX_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:stable \
|
|
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:stable
|
|
env:
|
|
NEEDS_SETUP_OUTPUTS_PROWLER_VERSION: ${{ needs.setup.outputs.prowler_version }}
|
|
|
|
# Re-login as prowlercloud for cleanup of intermediate tags
|
|
- name: Login to DockerHub (prowlercloud)
|
|
if: always()
|
|
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Install regctl
|
|
if: always()
|
|
uses: regclient/actions/regctl-installer@9a2d4216180dbb3e2dccfa60d2dd4afd98e42ec5 # main
|
|
|
|
- name: Cleanup intermediate architecture tags
|
|
if: always()
|
|
run: |
|
|
echo "Cleaning up intermediate tags..."
|
|
regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-amd64" || true
|
|
regctl tag delete "${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${NEEDS_SETUP_OUTPUTS_LATEST_TAG}-arm64" || true
|
|
echo "Cleanup completed"
|
|
env:
|
|
NEEDS_SETUP_OUTPUTS_LATEST_TAG: ${{ needs.setup.outputs.latest_tag }}
|
|
|
|
notify-release-completed:
|
|
if: always() && needs.notify-release-started.result == 'success' && (github.event_name == 'release' || github.event_name == 'workflow_dispatch')
|
|
needs: [setup, notify-release-started, container-build-push, create-manifest]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Harden the runner (Audit all outbound calls)
|
|
uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Determine overall outcome
|
|
id: outcome
|
|
run: |
|
|
if [[ "${NEEDS_CONTAINER_BUILD_PUSH_RESULT}" == "success" && "${NEEDS_CREATE_MANIFEST_RESULT}" == "success" ]]; then
|
|
echo "outcome=success" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "outcome=failure" >> $GITHUB_OUTPUT
|
|
fi
|
|
env:
|
|
NEEDS_CONTAINER_BUILD_PUSH_RESULT: ${{ needs.container-build-push.result }}
|
|
NEEDS_CREATE_MANIFEST_RESULT: ${{ needs.create-manifest.result }}
|
|
|
|
- name: Notify container push completed
|
|
uses: ./.github/actions/slack-notification
|
|
env:
|
|
SLACK_CHANNEL_ID: ${{ secrets.SLACK_PLATFORM_DEPLOYMENTS }}
|
|
MESSAGE_TS: ${{ needs.notify-release-started.outputs.message-ts }}
|
|
COMPONENT: SDK
|
|
RELEASE_TAG: ${{ needs.setup.outputs.prowler_version }}
|
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
with:
|
|
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
payload-file-path: "./.github/scripts/slack-messages/container-release-completed.json"
|
|
step-outcome: ${{ steps.outcome.outputs.outcome }}
|
|
update-ts: ${{ needs.notify-release-started.outputs.message-ts }}
|