Launch Push Docker Images - v5.0.0-latest_2026-04-23_09-24-19-699 #449
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| run-name: Launch Push Docker Images - ${{ inputs.id }} | |
| name: Push Docker Images | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| image_tag: | |
| description: 'Docker image tag' | |
| default: '5.0.0' | |
| required: true | |
| docker_reference: | |
| description: 'wazuh-docker reference' | |
| required: true | |
| wazuh_automation_reference: | |
| description: 'Branch or tag of the wazuh-automation repository' | |
| required: false | |
| default: 'main' | |
| products: | |
| description: 'Comma-separated list of the image names to build and push' | |
| default: 'wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent' | |
| required: false | |
| type: string | |
| commit_list: | |
| description: 'Wazuh components revisions (only for dev): json array with commit-hash for each product' | |
| type: string | |
| default: '["latest", "latest", "latest", "latest"]' | |
| assistant_revision: | |
| description: 'Revision for Wazuh installation assistant tools like Wazuh password tool (only for dev)' | |
| type: string | |
| default: 'latest' | |
| required: false | |
| id: | |
| description: "ID used to identify the workflow uniquely." | |
| type: string | |
| required: false | |
| dev: | |
| description: "Add tag suffix '-dev' to the image tag ?" | |
| type: boolean | |
| default: true | |
| required: false | |
| workflow_call: | |
| inputs: | |
| image_tag: | |
| description: 'Docker image tag' | |
| default: '5.0.0' | |
| required: true | |
| type: string | |
| docker_reference: | |
| description: 'wazuh-docker reference' | |
| required: false | |
| type: string | |
| wazuh_automation_reference: | |
| description: 'Branch or tag of the wazuh-automation repository' | |
| required: false | |
| default: 'main' | |
| type: string | |
| products: | |
| description: 'Comma-separated list of the image names to build and push' | |
| default: 'wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent' | |
| required: false | |
| type: string | |
| commit_list: | |
| description: 'Wazuh components revisions (only for dev): json array with commit-hash for each product' | |
| type: string | |
| default: '["latest", "latest", "latest", "latest"]' | |
| assistant_revision: | |
| description: 'Revision for Wazuh installation assistant tools like Wazuh password tool (only for dev)' | |
| type: string | |
| default: 'latest' | |
| required: false | |
| id: | |
| description: "ID used to identify the workflow uniquely." | |
| type: string | |
| required: false | |
| dev: | |
| description: "Add tag suffix '-dev' to the image tag ?" | |
| type: boolean | |
| default: false | |
| required: false | |
| permissions: | |
| id-token: write | |
| contents: read | |
| jobs: | |
| setup: | |
| runs-on: | |
| group: wz-linux-amd64 | |
| outputs: | |
| WAZUH_COMPONENTS: ${{ steps.compute-outputs.outputs.WAZUH_COMPONENTS }} | |
| COMMIT_LIST: ${{ steps.compute-outputs.outputs.COMMIT_LIST }} | |
| ALL_PRODUCTS_SELECTED: ${{ steps.compute-outputs.outputs.ALL_PRODUCTS_SELECTED }} | |
| steps: | |
| - name: Print inputs | |
| run: | | |
| echo "---------------------------------------------" | |
| echo "Running Procedure_push_docker_images workflow" | |
| echo "---------------------------------------------" | |
| echo "* BRANCH: ${{ github.ref }}" | |
| echo "* COMMIT: ${{ github.sha }}" | |
| echo "---------------------------------------------" | |
| echo "Inputs provided:" | |
| echo "---------------------------------------------" | |
| echo "* id: ${{ inputs.id }}" | |
| echo "* image_tag: ${{ inputs.image_tag }}" | |
| echo "* docker_reference: ${{ inputs.docker_reference }}" | |
| echo "* wazuh_automation_reference: ${{ inputs.wazuh_automation_reference }}" | |
| echo "* products: ${{ inputs.products }}" | |
| echo "* dev: ${{ inputs.dev }}" | |
| echo "* commit_list: ${{ inputs.commit_list }}" | |
| echo "* assistant_revision: ${{ inputs.assistant_revision }}" | |
| echo "---------------------------------------------" | |
| - name: Set up variables | |
| id: compute-outputs | |
| run: | | |
| # Use the default list if products is empty | |
| PRODUCTS="${{ inputs.products }}" | |
| if [[ -z "$PRODUCTS" || "$PRODUCTS" == "null" ]]; then | |
| PRODUCTS="wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent" | |
| fi | |
| # Check if all 4 core components are present in the string | |
| if [[ "$PRODUCTS" == *"wazuh-manager"* && "$PRODUCTS" == *"wazuh-dashboard"* && "$PRODUCTS" == *"wazuh-indexer"* && "$PRODUCTS" == *"wazuh-agent"* ]]; then | |
| echo "ALL_PRODUCTS_SELECTED=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "ALL_PRODUCTS_SELECTED=false" >> $GITHUB_OUTPUT | |
| fi | |
| # Set WAZUH_COMPONENTS | |
| # Convert to JSON for the matrix (Your existing logic) | |
| IFS=',' read -ra COMPONENTS <<< "$PRODUCTS" | |
| JSON_ARRAY=$(printf '%s\n' "${COMPONENTS[@]}" | jq -R . | jq -s -c .) | |
| echo "WAZUH_COMPONENTS=$JSON_ARRAY" >> $GITHUB_OUTPUT | |
| # Set COMMIT_LIST | |
| WC_COMMIT_LIST="" | |
| if [[ "${{ inputs.dev }}" == "true" ]]; then | |
| if [[ "${{ inputs.commit_list }}" != "null" && "${{ inputs.commit_list }}" != "" ]]; then | |
| WC_COMMIT_LIST='${{ inputs.commit_list }}' | |
| else | |
| # Set commit list to "latest" for all components using WAZUH_COMPONENTS | |
| COMPONENTS=($(echo "$WC_JSON_ARRAY" | jq -r '.[]')) | |
| WC_COMMIT_LIST="[" | |
| for i in "${!COMPONENTS[@]}"; do | |
| if [ $i -gt 0 ]; then | |
| WC_COMMIT_LIST+=" ," | |
| fi | |
| WC_COMMIT_LIST+="\"latest\"" | |
| done | |
| WC_COMMIT_LIST+="]" | |
| fi | |
| echo "Revision list: $WC_COMMIT_LIST" | |
| fi | |
| echo "COMMIT_LIST=$WC_COMMIT_LIST" >> $GITHUB_OUTPUT | |
| package-urls: | |
| name: generate package urls | |
| runs-on: | |
| group: wz-linux-amd64 | |
| needs: setup | |
| env: | |
| WORKFLOW_VENV: "${{ github.workspace }}/workflow_venv" | |
| GENERATE_PRESIGNED_URLS_SCRIPT_PATH: ${{ github.workspace }}/wazuh-automation/tools/sign_urls/generate_presigned_dev_urls.py | |
| PRESIGNED_URLS_SCRIPT_PROCESS: "build_docker" | |
| LOCAL_ARTIFACT_URLS_FILEPATH: /tmp/${{ vars.ARTIFACT_URL_FILE_NAME }} | |
| COMMIT_LIST: ${{ inputs.commit_list }} | |
| ASSISTANT_REVISION: ${{ inputs.assistant_revision }} | |
| steps: | |
| - name: Checkout repository | |
| if: ${{ inputs.dev == true }} | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ inputs.docker_reference }} | |
| - name: Checkout wazuh/wazuh-automation repository | |
| if: ${{ inputs.dev == true }} | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: wazuh/wazuh-automation | |
| ref: ${{ inputs.wazuh_automation_reference }} | |
| token: ${{ secrets.GH_CLONE_TOKEN }} | |
| path: wazuh-automation | |
| - name: Configure AWS credentials | |
| if: ${{ inputs.dev == true }} | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }} | |
| aws-region: ${{ secrets.AWS_REGION }} | |
| - name: Set up Python | |
| if: ${{ inputs.dev == true }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install and configure python and workflow dependencies | |
| if: ${{ inputs.dev == true }} | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y jq | |
| # Install yq | |
| sudo curl -sL "https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64" -o /usr/local/bin/yq | |
| sudo chmod +x /usr/local/bin/yq | |
| sudo apt-get install -y python3-venv | |
| python3 -m venv ${{ env.WORKFLOW_VENV }} | |
| source ${{ env.WORKFLOW_VENV }}/bin/activate | |
| pip install --upgrade pip | |
| pip install pyyaml | |
| - name: Get Wazuh version | |
| if: ${{ inputs.dev == true }} | |
| run: | | |
| WAZUH_VERSION=$(jq -r '.version' VERSION.json) | |
| WAZUH_MAJOR=$(echo "$WAZUH_VERSION" | cut -d '.' -f 1) | |
| WAZUH_MINOR=$(echo "$WAZUH_VERSION" | cut -d '.' -f 1-2) | |
| echo WAZUH_VERSION=$WAZUH_VERSION >> $GITHUB_ENV | |
| echo WAZUH_MAJOR=$WAZUH_MAJOR >> $GITHUB_ENV | |
| echo WAZUH_MINOR=$WAZUH_MINOR >> $GITHUB_ENV | |
| - name: Get artifacts URLs file | |
| if: ${{ inputs.dev == true }} | |
| run: | | |
| LOCAL_AWS_S3_BUCKET_DEV=${{ vars.AWS_S3_BUCKET_DEV }} | |
| echo LOCAL_AWS_S3_BUCKET_DEV=$LOCAL_AWS_S3_BUCKET_DEV >> $GITHUB_ENV | |
| - name: Generate presigned URLs for artifacts for dev packages | |
| if: ${{ inputs.dev == true }} | |
| run: | | |
| source ${{ env.WORKFLOW_VENV }}/bin/activate | |
| WAZUH_COMPONENTS='${{ needs.setup.outputs.WAZUH_COMPONENTS }}' | |
| COMMIT_LIST='${{ needs.setup.outputs.COMMIT_LIST }}' | |
| # Parse components and their revisions | |
| COMPONENTS=($(echo "$WAZUH_COMPONENTS" | jq -r '.[]')) | |
| REVISIONS=($(echo "$COMMIT_LIST" | jq -r '.[]')) | |
| # Ensure the number of components matches the number of revisions | |
| if [[ ${#COMPONENTS[@]} -ne ${#REVISIONS[@]} ]]; then | |
| echo "Error: WAZUH_COMPONENTS and COMMIT_LIST length mismatch." >&2 | |
| echo " Components: ${#COMPONENTS[@]}, Revisions: ${#REVISIONS[@]}." >&2 | |
| echo " WAZUH_COMPONENTS=${WAZUH_COMPONENTS}" >&2 | |
| echo " COMMIT_LIST=${COMMIT_LIST}" >&2 | |
| exit 1 | |
| fi | |
| # Map revisions to component names | |
| for i in "${!COMPONENTS[@]}"; do | |
| case "${COMPONENTS[$i]}" in | |
| wazuh-manager) | |
| MANAGER_REVISION="${REVISIONS[$i]}" | |
| ;; | |
| wazuh-dashboard) | |
| DASHBOARD_REVISION="${REVISIONS[$i]}" | |
| ;; | |
| wazuh-indexer) | |
| INDEXER_REVISION="${REVISIONS[$i]}" | |
| ;; | |
| wazuh-agent) | |
| AGENT_REVISION="${REVISIONS[$i]}" | |
| ;; | |
| esac | |
| done | |
| python ${{ env.GENERATE_PRESIGNED_URLS_SCRIPT_PATH }} \ | |
| --process ${{ env.PRESIGNED_URLS_SCRIPT_PROCESS }} \ | |
| --wazuh-version ${{ env.WAZUH_VERSION }} \ | |
| --aws-s3-bucket-dev ${{ env.LOCAL_AWS_S3_BUCKET_DEV }} \ | |
| --indexer-revision $INDEXER_REVISION \ | |
| --manager-revision $MANAGER_REVISION \ | |
| --dashboard-revision $DASHBOARD_REVISION \ | |
| --agent-revision $AGENT_REVISION \ | |
| --assistant-revision $ASSISTANT_REVISION | |
| - name: Save presigned URLs file to artifact | |
| if: ${{ inputs.dev == true }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: presigned-artifact-urls-${{ github.run_id }} | |
| path: ${{ env.LOCAL_ARTIFACT_URLS_FILEPATH }} | |
| build-and-push: | |
| runs-on: | |
| group: wz-linux-amd64 | |
| needs: | |
| - setup | |
| - package-urls | |
| strategy: | |
| fail-fast: false # all jobs will run even if one fails | |
| matrix: | |
| wazuh_component: ${{ fromJson(needs.setup.outputs.WAZUH_COMPONENTS) }} | |
| env: | |
| IMAGE_REGISTRY: ${{ inputs.dev && vars.IMAGE_REGISTRY_DEV || vars.IMAGE_REGISTRY_PROD }} | |
| IMAGE_TAG: ${{ inputs.image_tag }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.docker_reference }} | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Configure aws credentials | |
| if: ${{ inputs.dev == true }} | |
| uses: aws-actions/configure-aws-credentials@v6 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }} | |
| aws-region: "${{ secrets.AWS_REGION }}" | |
| - name: Log in to Amazon ECR | |
| if: ${{ inputs.dev == true }} | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Log in to Docker Hub | |
| if: ${{ inputs.dev == false }} | |
| uses: docker/login-action@v4 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_PASSWORD }} | |
| - name: Download artifact_urls.yaml (dev) | |
| if: ${{ inputs.dev == true }} | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: presigned-artifact-urls-${{ github.run_id }} | |
| path: ./build-docker-images | |
| - name: Compute component reference (dev) | |
| if: ${{ inputs.dev == true }} | |
| run: | | |
| COMPONENT='${{ matrix.wazuh_component }}' | |
| WAZUH_COMPONENTS='${{ needs.setup.outputs.WAZUH_COMPONENTS }}' | |
| COMMIT_LIST='${{ needs.setup.outputs.COMMIT_LIST }}' | |
| idx=$(jq -r --arg c "$COMPONENT" 'index($c)' <<<"$WAZUH_COMPONENTS") | |
| ref=$(jq -r --argjson i "$idx" '.[ $i ]' <<<"$COMMIT_LIST") | |
| echo "COMPONENT_REFS_JSON=[\"$ref\"]" >> "$GITHUB_ENV" | |
| echo "Using component ref for $COMPONENT: $ref" | |
| - name: Build Wazuh images | |
| run: | | |
| if [[ "$IMAGE_TAG" == *"-"* ]]; then | |
| IFS='-' read -r -a tokens <<< "$IMAGE_TAG" | |
| if [ -z "${tokens[1]}" ]; then | |
| echo "Invalid image tag: $IMAGE_TAG" | |
| exit 1 | |
| fi | |
| DEV_STAGE=${tokens[1]} | |
| WAZUH_VER=${tokens[0]} | |
| if [ "${{ inputs.dev }}" = true ]; then | |
| ./build-images.sh \ | |
| -v $WAZUH_VER \ | |
| -d $DEV_STAGE \ | |
| -rg $IMAGE_REGISTRY \ | |
| -m \ | |
| --dev \ | |
| -refs "$COMPONENT_REFS_JSON" \ | |
| -c ${{ matrix.wazuh_component }} | |
| else | |
| ./build-images.sh \ | |
| -v $WAZUH_VER \ | |
| -d $DEV_STAGE \ | |
| -rg $IMAGE_REGISTRY \ | |
| -m \ | |
| -c ${{ matrix.wazuh_component }} | |
| fi | |
| else | |
| if [ "${{ inputs.dev }}" = true ]; then | |
| ./build-images.sh \ | |
| -v $IMAGE_TAG \ | |
| -rg $IMAGE_REGISTRY \ | |
| -m \ | |
| --dev \ | |
| -refs "$COMPONENT_REFS_JSON" \ | |
| -c ${{ matrix.wazuh_component }} | |
| else | |
| ./build-images.sh \ | |
| -v $IMAGE_TAG \ | |
| -rg $IMAGE_REGISTRY \ | |
| -m \ | |
| -c ${{ matrix.wazuh_component }} | |
| fi | |
| fi | |
| # Save .env file (generated by build-images.sh) contents to $GITHUB_ENV | |
| ENV_FILE_PATH="../.env" | |
| if [ -f $ENV_FILE_PATH ]; then | |
| while IFS= read -r line || [ -n "$line" ]; do | |
| echo "$line" >> $GITHUB_ENV | |
| done < $ENV_FILE_PATH | |
| else | |
| echo "The environment file $ENV_FILE_PATH does not exist!" | |
| exit 1 | |
| fi | |
| working-directory: ./build-docker-images | |
| notify: | |
| runs-on: ubuntu-22.04 | |
| needs: [setup, build-and-push] | |
| # Only run if NOT dev AND all products were selected | |
| if: ${{ inputs.dev == false && needs.setup.outputs.ALL_PRODUCTS_SELECTED == 'true' }} | |
| steps: | |
| - name: Image exists validation | |
| id: validation | |
| run: | | |
| IMAGE_TAG=${{ inputs.image_tag }} | |
| IMAGE_REGISTRY="${{ vars.IMAGE_REGISTRY_PROD }}" | |
| PURPOSE="" | |
| if [[ "$IMAGE_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| if docker manifest inspect $IMAGE_REGISTRY/wazuh/wazuh-manager:$IMAGE_TAG > /dev/null 2>&1; then | |
| PURPOSE="regeneration" | |
| echo "Image wazuh/wazuh-manager:$IMAGE_TAG exists. Setting PURPOSE to 'regeneration'" | |
| else | |
| PURPOSE="new release" | |
| echo "Image wazuh/wazuh-manager:$IMAGE_TAG does NOT exist. Setting PURPOSE to 'new release'" | |
| fi | |
| echo "✅ Release tag: '$IMAGE_TAG'" | |
| elif [[ "$IMAGE_TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+-(alpha|beta|rc)[0-9]+$ ]]; then | |
| PURPOSE="new stage" | |
| echo "✅ Stage tag: '$IMAGE_TAG'. Setting PURPOSE to 'new stage'" | |
| else | |
| echo "❌ No release or stage tag ('$IMAGE_TAG'), the GH issue will not be created" | |
| fi | |
| echo "purpose=$PURPOSE" >> $GITHUB_OUTPUT | |
| - name: GH issue notification | |
| if: ${{ steps.validation.outputs.purpose != '' }} | |
| env: | |
| GH_TOKEN: ${{ secrets.NOTIFICATION_GH_ARTIFACT_TOKEN }} | |
| run: | | |
| IMAGE_TAG=${{ inputs.image_tag }} | |
| PURPOSE="${{ steps.validation.outputs.purpose }}" | |
| GH_TITLE="" | |
| GH_MESSAGE="" | |
| ## Setting GH issue title | |
| GH_TITLE="Artifactory vulnerabilities update \`v$IMAGE_TAG\`" | |
| ## Setting GH issue body | |
| GH_MESSAGE=$(cat <<- EOF | tr -d '\r' | sed 's/^[[:space:]]*//' | |
| ### Description | |
| - [ ] Update the [Artifactory vulnerabilities](${{ secrets.NOTIFICATION_SHEET_URL }}) sheet with the \`v$IMAGE_TAG\` vulnerabilities. | |
| **Purpose**: $PURPOSE | |
| >[!NOTE] | |
| >To update the \`Tentative Release\` column, follow these steps: | |
| https://github.com/wazuh/${{ secrets.NOTIFICATION_REPO }}/issues/2049#issuecomment-2671590268 | |
| EOF | |
| ) | |
| # Print the GH Variables content | |
| echo "--- Variable Content ---" | |
| echo "$GH_TITLE" | |
| echo "------------------------" | |
| echo "--- Variable Content ---" | |
| echo "$GH_MESSAGE" | |
| echo "------------------------" | |
| ## GH issue creation | |
| ISSUE_URL=$(gh issue create \ | |
| -R wazuh/${{ secrets.NOTIFICATION_REPO }} \ | |
| --title "$GH_TITLE" \ | |
| --body "$GH_MESSAGE" \ | |
| --label "level/task" \ | |
| --label "type/maintenance" \ | |
| --label "request/operational") | |
| ## Adding the issue to the team project | |
| PROJECT_ITEM_ID=$(gh project item-add \ | |
| ${{ secrets.NOTIFICATION_PROJECT_NUMBER }} \ | |
| --url $ISSUE_URL \ | |
| --owner wazuh \ | |
| --format json \ | |
| | jq -r '.id') | |
| ## Setting Objective | |
| gh project item-edit --id $PROJECT_ITEM_ID --project-id ${{ secrets.NOTIFICATION_PROJECT_ID }} --field-id ${{ secrets.NOTIFICATION_PROJECT_OBJECTIVE_ID }} --text "Security scans" | |
| ## Setting Priority | |
| gh project item-edit --id $PROJECT_ITEM_ID --project-id ${{ secrets.NOTIFICATION_PROJECT_ID }} --field-id ${{ secrets.NOTIFICATION_PROJECT_PRIORITY_ID }} --single-select-option-id ${{ secrets.NOTIFICATION_PROJECT_PRIORITY_OPTION_ID }} | |
| ## Setting Size | |
| gh project item-edit --id $PROJECT_ITEM_ID --project-id ${{ secrets.NOTIFICATION_PROJECT_ID }} --field-id ${{ secrets.NOTIFICATION_PROJECT_SIZE_ID }} --single-select-option-id ${{ secrets.NOTIFICATION_PROJECT_SIZE_OPTION_ID }} | |
| ## Setting Subteam | |
| gh project item-edit --id $PROJECT_ITEM_ID --project-id ${{ secrets.NOTIFICATION_PROJECT_ID }} --field-id ${{ secrets.NOTIFICATION_PROJECT_SUBTEAM_ID }} --single-select-option-id ${{ secrets.NOTIFICATION_PROJECT_SUBTEAM_OPTION_ID }} |