Build pdf-service #872
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
| name: Build Pipeline | |
| run-name: Build ${{ github.event.inputs.pipeline_name }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| pipeline_name: | |
| description: 'Name of the config pipeline to build' | |
| required: true | |
| type: choice | |
| options: | |
| - billing-service | |
| - collection-services | |
| - egf-instrument | |
| - egf-master | |
| - egov-apportion-service | |
| - egov-hrms | |
| - finance-collections-voucher-consumer | |
| - dashboard-analytics | |
| - dashboard-ingest | |
| - egov-accesscontrol | |
| - audit-service | |
| - egov-common-masters | |
| - egov-data-uploader | |
| - egov-enc-service | |
| - egov-filestore | |
| - egov-idgen | |
| - egov-indexer | |
| - egov-localization | |
| - egov-location | |
| - boundary-service | |
| - egov-mdms-service | |
| - mdms-v2 | |
| - egov-notification-mail | |
| - egov-notification-sms | |
| - egov-otp | |
| - egov-persister | |
| - egov-pg-service | |
| - egov-searcher | |
| - egov-telemetry | |
| - egov-user | |
| - egov-user-event | |
| - egov-workflow-v2 | |
| - egov-document-uploader | |
| - national-dashboard-ingest | |
| - national-dashboard-kafka-pipeline | |
| - egov-survey-services | |
| - report | |
| - tenant | |
| - user-otp | |
| - zuul | |
| - gateway | |
| - internal-gateway | |
| - internal-gateway-scg | |
| - pdf-service | |
| - egov-telemetry-kafka-streams | |
| - egov-telemetry-batch-process | |
| - egov-url-shortening | |
| - chatbot | |
| - http-to-kafka-connector | |
| - egov-user-chatbot | |
| - mailbot | |
| - enc-client | |
| - mdms-client | |
| - tracer | |
| - digit-models | |
| - services-common | |
| - nlp-engine | |
| - xstate-chatbot | |
| - xstate-webchat | |
| - inbox | |
| - gateway-kubernetes-discovery | |
| - pgr-services | |
| - service-request | |
| - default-data-handler | |
| - TenantManagement | |
| - keycloak-spi | |
| - pgr-ai-chatbot | |
| - workbench-ui | |
| - storybook-svg | |
| - storybook | |
| - digit-ui | |
| - egov-birth-service | |
| - sunbirdrc-credential-service | |
| - qr-scanner-ui | |
| - im-services-analytics | |
| - vault-enc-service | |
| env: | |
| DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }} | |
| DOCKER_PASSWORD: ${{ secrets.DOCKER_ACCESS_TOKEN }} | |
| jobs: | |
| resolve-config: | |
| name: Resolve config | |
| runs-on: ubuntu-latest | |
| outputs: | |
| service_work_dir: ${{ steps.setenv.outputs.SERVICE_WORK_DIR }} | |
| service_image_name: ${{ steps.setenv.outputs.SERVICE_IMAGE_NAME }} | |
| service_dockerfile: ${{ steps.setenv.outputs.SERVICE_DOCKERFILE }} | |
| db_folder_exists: ${{ steps.check-db-folder.outputs.folder_exists }} | |
| db_work_dir: ${{ steps.setenv.outputs.DB_WORK_DIR }} | |
| db_image_name: ${{ steps.setenv.outputs.DB_IMAGE_NAME }} | |
| db_dockerfile: ${{ steps.setenv.outputs.DB_DOCKERFILE }} | |
| tag: ${{ steps.tag.outputs.tag }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v3 | |
| - name: Install yq | |
| run: | | |
| VERSION="4.30.8" | |
| URL="https://github.com/mikefarah/yq/releases/download/v${VERSION}/yq_linux_amd64" | |
| sudo curl -sSL "$URL" -o /usr/local/bin/yq | |
| sudo chmod +x /usr/local/bin/yq | |
| - name: Resolve env from build-config.yml | |
| id: setenv | |
| run: | | |
| PIPELINE_NAME="${{ github.event.inputs.pipeline_name }}" | |
| DEFAULT_DOCKERFILE="Dockerfile" | |
| echo "### Pipeline Name - $PIPELINE_NAME" >> $GITHUB_STEP_SUMMARY | |
| # Step 1: List matching config blocks | |
| MATCHING_CONFIGS=$(yq eval -o=json '.config[] | select(.name | test("/'"$PIPELINE_NAME"'$"))' build/build-config.yml) | |
| # Step 2: Show matched config(s) | |
| echo "Matching config(s) for pipeline '$PIPELINE_NAME':" | |
| echo "$MATCHING_CONFIGS" | yq eval -P - # pretty-print for readability | |
| # Step 3: Check count of matching configs | |
| MATCH_COUNT=$(echo "$MATCHING_CONFIGS" | yq eval -o=json '.' - | jq -s 'length') | |
| if [ "$MATCH_COUNT" -ne 1 ]; then | |
| echo "ERROR: Expected exactly 1 matching pipeline config, but found $MATCH_COUNT" | |
| exit 1 | |
| fi | |
| # Step 4: Extract service build config (image-name not ending with -db) | |
| SERVICE_BUILD_CONFIG=$(yq eval -o=json ' | |
| .config[] | |
| | select(.name | test("/'"$PIPELINE_NAME"'$")) | |
| | .build[] | |
| | select(.["image-name"] | test("-db$") | not) | |
| ' build/build-config.yml) | |
| # Step 5: Extract db build config (image-name ending with -db) | |
| DB_BUILD_CONFIG=$(yq eval -o=json ' | |
| .config[] | |
| | select(.name | test("/'"$PIPELINE_NAME"'$")) | |
| | .build[] | |
| | select(.["image-name"] | test("-db$")) | |
| ' build/build-config.yml) | |
| # Step 6: Print for confirmation | |
| echo "SERVICE_BUILD_CONFIG: $SERVICE_BUILD_CONFIG" | |
| echo "DB_BUILD_CONFIG: $DB_BUILD_CONFIG" | |
| # Step 7: Extract Required Environment Variables | |
| SERVICE_DOCKERFILE=$(echo "$SERVICE_BUILD_CONFIG" | yq eval -r '.dockerfile // ""' -) | |
| SERVICE_IMAGE_NAME=$(echo "$SERVICE_BUILD_CONFIG" | yq eval -r '.["image-name"] // ""' -) | |
| SERVICE_WORK_DIR=$(echo "$SERVICE_BUILD_CONFIG" | yq eval -r '.["work-dir"] // ""' -) | |
| DB_IMAGE_NAME=$(echo "$DB_BUILD_CONFIG" | yq eval -r '.["image-name"] // ""' -) | |
| DB_WORK_DIR=$(echo "$DB_BUILD_CONFIG" | yq eval -r '.["work-dir"] // ""' -) | |
| DB_DOCKERFILE=$(echo "$DB_BUILD_CONFIG" | yq eval -r '.["work-dir"] // ""' -)/Dockerfile | |
| # Step 8: Set Default Dockerfile if service dockerfile config is missing | |
| if [ -z "$SERVICE_DOCKERFILE" ]; then | |
| echo "No dockerfile entry found for \"$SERVICE\" in build-config.yml; using default" | |
| SERVICE_DOCKERFILE="$SERVICE_WORK_DIR/$DEFAULT_DOCKERFILE" | |
| fi | |
| # Step 9: Export to github environment | |
| echo "SERVICE_WORK_DIR=$SERVICE_WORK_DIR" >> "$GITHUB_OUTPUT" | |
| echo "SERVICE_IMAGE_NAME=$SERVICE_IMAGE_NAME" >> "$GITHUB_OUTPUT" | |
| echo "SERVICE_DOCKERFILE=$SERVICE_DOCKERFILE" >> "$GITHUB_OUTPUT" | |
| echo "DB_WORK_DIR=$DB_WORK_DIR" >> "$GITHUB_OUTPUT" | |
| echo "DB_IMAGE_NAME=$DB_IMAGE_NAME" >> "$GITHUB_OUTPUT" | |
| echo "DB_DOCKERFILE=$DB_DOCKERFILE" >> "$GITHUB_OUTPUT" | |
| missing_vars=() | |
| # Step 10: Check if required env variables exists | |
| for var in SERVICE_WORK_DIR SERVICE_IMAGE_NAME SERVICE_DOCKERFILE; do | |
| if [ -z "${!var}" ]; then | |
| echo "ERROR: $var is not set or is empty" | |
| missing_vars+=("$var") | |
| fi | |
| done | |
| if [ ${#missing_vars[@]} -gt 0 ]; then | |
| echo "Required environment variables are missing: ${missing_vars[*]}" | |
| exit 1 # Fail the step | |
| fi | |
| # Step 11. Put summary for the step | |
| echo "#### Application Config Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "Application Work Directory - $SERVICE_WORK_DIR" >> $GITHUB_STEP_SUMMARY | |
| echo "Image Name - $SERVICE_IMAGE_NAME" >> $GITHUB_STEP_SUMMARY | |
| echo "Dockerfile Path - $SERVICE_DOCKERFILE" >> $GITHUB_STEP_SUMMARY | |
| echo "#### DB Config Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "Application Work Directory - $DB_WORK_DIR" >> $GITHUB_STEP_SUMMARY | |
| echo "Image Name - $DB_IMAGE_NAME" >> $GITHUB_STEP_SUMMARY | |
| echo "Dockerfile Path - $SERVICE_DOCKERFILE" >> $GITHUB_STEP_SUMMARY | |
| - name: Check if DB folder exists | |
| id: check-db-folder | |
| run: | | |
| FOLDER_PATH="${{ steps.setenv.outputs.DB_WORK_DIR }}" | |
| if [ -d "$FOLDER_PATH" ]; then | |
| echo "folder_exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "folder_exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate the Next Tag | |
| id: tag | |
| run: | | |
| set -euxo pipefail | |
| BRANCH="${GITHUB_REF##*/}" | |
| COMMIT_HASH=$(git rev-parse --short HEAD) | |
| SERVICE_NAME="${{ steps.setenv.outputs.SERVICE_IMAGE_NAME }}" | |
| TOKEN=$(curl -s -X POST "https://hub.docker.com/v2/users/login/" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"username\": \"$DOCKER_USERNAME\", \"password\": \"$DOCKER_PASSWORD\"}" \ | |
| | jq -r .token) | |
| if [ -z "$TOKEN" ]; then | |
| echo "Failed to authenticate with Docker Hub." >&2 | |
| exit 1 | |
| fi | |
| # Check if repo exists | |
| HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' \ | |
| -H "Authorization: JWT $TOKEN" \ | |
| "https://hub.docker.com/v2/repositories/$DOCKER_USERNAME/$SERVICE_NAME/") | |
| if [ "$HTTP_CODE" -ne 200 ]; then | |
| NEXT_TAG="${BRANCH}-${COMMIT_HASH}" | |
| else | |
| EXISTING_TAGS=$(curl -s -H "Authorization: JWT $TOKEN" \ | |
| "https://hub.docker.com/v2/repositories/$DOCKER_USERNAME/$SERVICE_NAME/tags?page_size=100" \ | |
| | jq -r '.results[].name') | |
| LATEST_TAG=$(echo "$EXISTING_TAGS" \ | |
| | grep "^${BRANCH}-${COMMIT_HASH}" || true \ | |
| | sort -V \ | |
| | tail -n 1) | |
| NEXT_TAG="${LATEST_TAG:-${BRANCH}-${COMMIT_HASH}}" | |
| fi | |
| echo "tag=$NEXT_TAG" >> "$GITHUB_OUTPUT" | |
| echo "NEXT_TAG=$NEXT_TAG" >> "$GITHUB_ENV" | |
| echo "tag - $NEXT_TAG" >> $GITHUB_STEP_SUMMARY | |
| build-matrix: | |
| name: Build image for ${{ matrix.arch }} | |
| needs: resolve-config | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| platform: linux/amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| runs-on: ${{ matrix.runner }} | |
| outputs: | |
| amd64_digest: ${{ steps.digest_amd64.outputs.digest }} | |
| amd64_digest_db: ${{ steps.digest_db_amd64.outputs.digest }} | |
| arm64_digest: ${{ steps.digest_arm64.outputs.digest }} | |
| arm64_digest_db: ${{ steps.digest_db_arm64.outputs.digest }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Cache Docker Layers | |
| uses: actions/cache@v3 | |
| with: | |
| path: /tmp/.buildx-cache | |
| key: ${{ runner.os }}-${{ matrix.arch }}-buildx-${{ github.event.inputs.pipeline_name }}-${{ github.ref_name }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.arch }}-buildx-${{ github.event.inputs.pipeline_name }}- | |
| - name: Docker Login | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ env.DOCKER_USERNAME }} | |
| password: ${{ env.DOCKER_PASSWORD }} | |
| - name: Build and Push Application Image | |
| run: | | |
| docker buildx build \ | |
| --platform ${{ matrix.platform }} \ | |
| --build-arg WORK_DIR=${{ needs.resolve-config.outputs.service_work_dir }} \ | |
| --file ${{ needs.resolve-config.outputs.service_dockerfile }} \ | |
| --tag egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --cache-from=type=local,src=/tmp/.buildx-cache \ | |
| --cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \ | |
| --push \ | |
| --iidfile digest.txt \ | |
| . | |
| - name: Build and Push DB Image | |
| if: ${{ needs.resolve-config.outputs.db_folder_exists == 'true' }} | |
| run: | | |
| docker buildx build \ | |
| --platform ${{ matrix.platform }} \ | |
| --build-arg WORK_DIR=${{ needs.resolve-config.outputs.db_work_dir }} \ | |
| --file ${{ needs.resolve-config.outputs.db_dockerfile }} \ | |
| --tag egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --cache-from=type=local,src=/tmp/.buildx-cache \ | |
| --cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \ | |
| --push \ | |
| --iidfile db-digest.txt \ | |
| ${{ needs.resolve-config.outputs.db_work_dir }} | |
| - name: Inspect Service Image Manifest List | |
| run: | | |
| docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} | |
| - name: Inspect DB Image Manifest List | |
| if: ${{ needs.resolve-config.outputs.db_folder_exists == 'true' }} | |
| run: | | |
| docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} | |
| - name: Export Digest Service (amd64) | |
| if: matrix.arch == 'amd64' | |
| id: digest_amd64 | |
| run: | | |
| digest=$(docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --format '{{json .}}' | jq -r '.manifest.manifests[] | select(.platform.architecture=="${{ matrix.arch }}") | .digest') | |
| echo "digest=$digest" >> $GITHUB_OUTPUT | |
| - name: Export Digest Service (arm64) | |
| if: matrix.arch == 'arm64' | |
| id: digest_arm64 | |
| run: | | |
| digest=$(docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --format '{{json .}}' | jq -r '.manifest.manifests[] | select(.platform.architecture=="${{ matrix.arch }}") | .digest') | |
| echo "digest=$digest" >> $GITHUB_OUTPUT | |
| - name: Export Digest DB (amd64) | |
| if: matrix.arch == 'amd64' && needs.resolve-config.outputs.db_folder_exists == 'true' | |
| id: digest_db_amd64 | |
| run: | | |
| digest=$(docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --format '{{json .}}' | jq -r '.manifest.manifests[] | select(.platform.architecture=="${{ matrix.arch }}") | .digest') | |
| echo "digest=$digest" >> $GITHUB_OUTPUT | |
| - name: Export Digest DB (arm64) | |
| if: matrix.arch == 'arm64' && needs.resolve-config.outputs.db_folder_exists == 'true' | |
| id: digest_db_arm64 | |
| run: | | |
| digest=$(docker buildx imagetools inspect egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-${{ matrix.arch }} \ | |
| --format '{{json .}}' | jq -r '.manifest.manifests[] | select(.platform.architecture=="${{ matrix.arch }}") | .digest') | |
| echo "digest=$digest" >> $GITHUB_OUTPUT | |
| create-manifest: | |
| name: Create and Push Manifest | |
| needs: [resolve-config, build-matrix] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Docker Login | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ env.DOCKER_USERNAME }} | |
| password: ${{ env.DOCKER_PASSWORD }} | |
| - name: Create and Push Docker Manifest (Application) | |
| run: | | |
| docker manifest create egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }} \ | |
| --amend egovio/${{ needs.resolve-config.outputs.service_image_name }}@${{ needs.build-matrix.outputs.amd64_digest }} \ | |
| --amend egovio/${{ needs.resolve-config.outputs.service_image_name }}@${{ needs.build-matrix.outputs.arm64_digest }} | |
| docker manifest push egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }} | |
| - name: Create and Push Docker Manifest (DB) | |
| if: needs.resolve-config.outputs.db_folder_exists == 'true' | |
| run: | | |
| docker manifest create egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }} \ | |
| --amend egovio/${{ needs.resolve-config.outputs.db_image_name }}@${{ needs.build-matrix.outputs.amd64_digest_db }} \ | |
| --amend egovio/${{ needs.resolve-config.outputs.db_image_name }}@${{ needs.build-matrix.outputs.arm64_digest_db }} | |
| docker manifest push egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }} | |
| - name: Cleanup local manifest refs (Application) | |
| run: | | |
| docker manifest rm egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-amd64 || true | |
| docker manifest rm egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}-arm64 || true | |
| - name: Cleanup local manifest refs (DB) | |
| if: needs.resolve-config.outputs.db_folder_exists == 'true' | |
| run: | | |
| docker manifest rm egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-amd64 || true | |
| docker manifest rm egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}-arm64 || true | |
| - name: Add Summary (Application) | |
| run: | | |
| echo "### Application Docker Manifest Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "- Image: egovio/${{ needs.resolve-config.outputs.service_image_name }}:${{ needs.resolve-config.outputs.tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Platforms: amd64, arm64" >> $GITHUB_STEP_SUMMARY | |
| - name: Add Summary (Application) | |
| run: | | |
| echo "### DB Docker Manifest Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "- Image: egovio/${{ needs.resolve-config.outputs.db_image_name }}:${{ needs.resolve-config.outputs.tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Platforms: amd64, arm64" >> $GITHUB_STEP_SUMMARY |