diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..64e382d1d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,72 @@ +name: "Build" +on: + pull_request: + types: [opened, synchronize, reopened] + branches: + - develop + push: + branches: + - develop + +jobs: + tests: + name: Tests + uses: ./.github/workflows/test.yml + + generate-build-id: + name: "Generate Build Id" + needs: [ tests ] + runs-on: ubuntu-latest + outputs: + build-id: ${{ steps.generate.outputs.buildId }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - id: generate + working-directory: ./scripts + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + chmod +x ./create_build_id.sh + + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + GIT_BRANCH=PR + elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then + GIT_BRANCH=main + fi + + BUILD_ID=$(./create_build_id.sh $GIT_BRANCH ${{ github.run_number }} ${{ github.sha }}) + echo "Generated the build tag: $BUILD_ID" + echo "buildId=$BUILD_ID" >> "$GITHUB_OUTPUT" + + publish-docker-image: + name: "Publish docker image to ECR" + needs: [ generate-build-id ] + + uses: ./.github/workflows/publish.yml + with: + directory: . + repository: nhais + build-context: . + build-id: ${{ needs.generate-build-id.outputs.build-id }} + secrets: inherit + + comment: + if: github.event_name == 'pull_request' + name: "Create Build ID Comment" + needs: [ generate-build-id, publish-docker-image] + continue-on-error: true + permissions: + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Comment PR + uses: thollander/actions-comment-pull-request@v3 + with: + message: | + Images built and published to ECR using a Build Id of ${{ needs.generate-build-id.outputs.build-id }} + comment-tag: images-built + mode: upsert + diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..ae12ee333 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,58 @@ +name: Publish Workflow +on: + workflow_call: + inputs: + directory: + required: true + type: string + repository: + required: true + type: string + build-context: + required: true + type: string + build-id: + required: true + type: string + +jobs: + build-and-publish-docker-image: + name: Build & Publish Docker Image + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: gp2gp_github_action_build_workflow + aws-region: ${{ secrets.AWS_REGION }} + + - name: Build Docker Image + run: | + DOCKER_REGISTRY="${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com" + DOCKER_TAG="$DOCKER_REGISTRY/${{ inputs.repository }}:${{ inputs.build-id }}" + echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV + + # Build Image + docker build -f ./${{ inputs.directory }}/Dockerfile -t $DOCKER_TAG ${{ inputs.build-context }} + + - name: Login to AWS ECR + run: | + DOCKER_REGISTRY="https://${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com" + aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin $DOCKER_REGISTRY + + - name: Publish image to ECR + run: docker push $DOCKER_TAG + + - name: Logout of AWS ECR (Clean up Credentials) + if: always() + run: | + DOCKER_REGISTRY="https://${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com" + docker logout $DOCKER_REGISTRY \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..f1035f4c4 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,143 @@ +name: Test Workflow +on: + workflow_call: + +jobs: + unit-tests: + name: Unit Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 11 + uses: actions/setup-java@v4 + with: + java-version: 11 + distribution: temurin + + - name: Execute Unit Tests + run: ./gradlew test --parallel --build-cache + + - name: Collect Artifacts + if: always() + run: | + mkdir -p artifacts + cp -r ./build/reports ./artifacts + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: Unit Test Report + path: ./artifacts/** + compression-level: 9 + + - name: Test Job Summary + if: always() + uses: test-summary/action@v2 + with: + paths: ./build/test-results/test/TEST-*.xml + + - name: Temporary Artifacts Cleanup + run: rm -rf ./artifacts + + component-tests: + name: Component Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 11 + uses: actions/setup-java@v4 + with: + java-version: 11 + distribution: temurin + + - name: Execute Component Tests + run: ./gradlew componentTest --build-cache + + - name: Collect Artifacts + if: always() + run: | + mkdir -p artifacts + cp -r ./build/reports ./artifacts + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: Component Test Report + path: ./artifacts/** + compression-level: 9 + + - name: Test Job Summary + if: always() + uses: test-summary/action@v2 + with: + paths: ./build/test-results/componentTest/TEST-*.xml + + - name: Temporary Artifacts Cleanup + run: rm -rf ./artifacts + + integration_tests: + name: Integration Tests + permissions: + id-token: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: 11 + distribution: temurin + + - name: Setup Required Docker Images + run: docker compose up mongodb activemq fake-mesh -d + + - name: Execute Integration Tests + run: ./gradlew integrationTest + + - name: Dump Docker Logs + if: always() + run: | + mkdir -p ./logs + container_names=$(docker ps -a --format '{{.Names}}') + for container in $container_names; do + docker logs "$container" > ./logs/"$container".log + echo "Logs saved for container: $container" + done + shell: bash + + - name: Collect Artifacts + if: always() + run: | + mkdir -p artifacts + cp -r ./build/reports ./artifacts + cp -r ./logs ./artifacts + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: Integration Test Report & Docker Logs + path: ./artifacts/** + compression-level: 9 + + - name: Test Job Summary + if: always() + uses: test-summary/action@v2 + with: + paths: ./build/test-results/integrationTest/TEST-*.xml + + - name: Stop Docker Dependencies + if: always() + run: docker compose down --rmi=local --remove-orphans + + - name: Temporary Artifacts Cleanup + run: rm -rf ./artifacts diff --git a/scripts/create_build_id.sh b/scripts/create_build_id.sh new file mode 100644 index 000000000..758ae0094 --- /dev/null +++ b/scripts/create_build_id.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +clean_tag_element() { + local tag_element="$1" + echo "${tag_element//\//-}" +} + +generate_tag() { + local clean_branch_name + clean_branch_name=$(clean_tag_element "$1") + local clean_build_id + clean_build_id=$(clean_tag_element "$2") + local git_hash="$3" + + local tag="${clean_branch_name}-${clean_build_id}-${git_hash:0:7}" + + echo "$tag" +} + +if [[ $# -ne 3 ]]; then + echo "Usage: $0 branch_name build_id git_hash" + exit 1 +fi + +branch_name="$1" +build_id="$2" +git_hash="$3" + +generate_tag "$branch_name" "$build_id" "$git_hash" diff --git a/src/intTest/java/uk/nhs/digital/nhsconnect/nhais/container/MongoDbContainer.java b/src/intTest/java/uk/nhs/digital/nhsconnect/nhais/container/MongoDbContainer.java index b26322b0f..223e11a9e 100644 --- a/src/intTest/java/uk/nhs/digital/nhsconnect/nhais/container/MongoDbContainer.java +++ b/src/intTest/java/uk/nhs/digital/nhsconnect/nhais/container/MongoDbContainer.java @@ -7,7 +7,7 @@ public class MongoDbContainer extends GenericContainer { public static final int MONGODB_PORT = 27017; - public static final String DEFAULT_IMAGE_AND_TAG = "mongo:3.2.4"; + public static final String DEFAULT_IMAGE_AND_TAG = "mongo:8.0"; private static MongoDbContainer container; private MongoDbContainer() {