diff --git a/.github/workflows/build-image-push-action.yaml b/.github/workflows/build-image-push-action.yaml new file mode 100644 index 0000000..1f46344 --- /dev/null +++ b/.github/workflows/build-image-push-action.yaml @@ -0,0 +1,36 @@ +name: Build and Push Docker Image + +on: + push: + paths: + - 'build-push-image/**' + branches: + - main + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Google Cloud authentication + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ secrets.GCP_CREDENTIALS }} + + - name: Configure Docker to use the Google Cloud registry + run: | + gcloud --quiet auth configure-docker + + - name: Build Docker image + run: | + IMAGE="gcr.io/${{ secrets.GCP_PROJECT_ID }}/build-push-image:latest" + docker build -t $IMAGE ./build-push-image + + - name: Push Docker image to Google Container Registry + run: | + IMAGE="gcr.io/${{ secrets.GCP_PROJECT_ID }}/build-push-image:latest" + docker push $IMAGE + diff --git a/.github/workflows/code-quality.yaml b/.github/workflows/code-quality.yaml new file mode 100644 index 0000000..e1a9b17 --- /dev/null +++ b/.github/workflows/code-quality.yaml @@ -0,0 +1,157 @@ +name: code-quality + +on: + workflow_call: + # code quality em flow separado pois necessita rodar em runner especifico. + + inputs: + git_ref: + description: 'A referência do Git (branch, tag, SHA) a ser buildada/deployada' + required: true + type: string + SONAR_BDSP_HOST_URL: + description: 'URL do host do SonarQube' + required: true + type: string + java_version: + description: 'Versão do Java a ser usada' + required: true + type: string + + + secrets: + SONAR_BDSP_TOKEN: + description: 'Token de acesso ao SonarQube' + required: true +env: + SONAR_LANGUAGE: "java" + SONAR_MAIN_BRANCH: "master" + SONAR_VISIBILITY: "private" + SONAR_QUALITY_PROFILE: "Sonar way" + SONAR_QUALITY_GATE: "QG_PNB_BACKEND" + SONAR_PERMISSION_TEMPLATE: "PNB-TEMPLATE" + SONAR_NEW_CODE_DEF_TYPE: "PREVIOUS_VERSION" + JAVA_VERSION: ${{ inputs.java_version }} + +jobs: + Code-Quality: + runs-on: runner-pb-pefisa + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.git_ref }} + fetch-depth: 0 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '${{ env.JAVA_VERSION }}' + + - name: Build and Test with Maven + run: | + mvn clean package dependency:copy-dependencies -DoutputDirectory=./lib + + - name: Check project existence in SonarQube + id: checkSonarProjectExistence + run: | + set -e + echo "Verificando se o projeto existe no SonarQube..." + + RESPONSE=$(curl --verbose --fail --location \ + "${{ inputs.SONAR_BDSP_HOST_URL }}/api/projects/search?projects=${{ github.event.repository.name }}" \ + --header "Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}") + + echo "$RESPONSE" + + FOUND_PROJECTS=$(echo "$RESPONSE" | jq -r '.paging.total' 2>/dev/null || echo "0") + + echo "FOUND_PROJECTS: $FOUND_PROJECTS" + + if [[ "$FOUND_PROJECTS" =~ ^[0-9]+$ && "$FOUND_PROJECTS" -eq 0 ]]; then + echo "exists=false" >> "$GITHUB_OUTPUT" + else + echo "exists=true" >> "$GITHUB_OUTPUT" + fi + + - name: Creating new project on SonarQube + if: steps.checkSonarProjectExistence.outputs.exists == 'false' + run: | + set -e + echo "Criando projeto no SonarQube..." + curl -f --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/projects/create' \ + --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data-urlencode 'project=${{ github.event.repository.name }}' \ + --data-urlencode 'name=${{ github.event.repository.name }}' \ + --data-urlencode 'mainBranch=${{env.SONAR_MAIN_BRANCH}}' \ + --data-urlencode 'newCodeDefinitionType=${{env.SONAR_NEW_CODE_DEF_TYPE}}' \ + --data-urlencode 'visibility=${{env.SONAR_VISIBILITY}}' + + - name: Configuring quality gate + if: steps.checkSonarProjectExistence.outputs.exists == 'false' + run: | + set -e + echo "Atribuindo Quality Gate ao projeto..." + curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/qualitygates/select' \ + --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data-urlencode 'gateName=${{env.SONAR_QUALITY_GATE}}' \ + --data-urlencode 'projectKey=${{ github.event.repository.name }}' + + - name: Configuring quality profile + if: steps.checkSonarProjectExistence.outputs.exists == 'false' + run: | + set -e + echo "Atribuindo Quality Profile..." + curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/qualityprofiles/add_project' \ + --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data-urlencode 'language=${{env.SONAR_LANGUAGE}}' \ + --data-urlencode 'qualityProfile=${{env.SONAR_QUALITY_PROFILE}}' \ + --data-urlencode 'project=${{ github.event.repository.name }}' + + - name: Applying template permission + if: steps.checkSonarProjectExistence.outputs.exists == 'false' + run: | + set -e + echo "Atribuindo Permission Template..." + curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/permissions/apply_template' \ + --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ + --header 'Content-Type: application/x-www-form-urlencoded' \ + --data-urlencode 'projectKey=${{ github.event.repository.name }}' \ + --data-urlencode 'templateName=${{env.SONAR_PERMISSION_TEMPLATE}}' + + - name: Get project version + run: echo "PROJECT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV + + - name: SonarQube Scan + uses: sonarsource/sonarqube-scan-action@master + env: + SONAR_HOST_URL: ${{ inputs.SONAR_BDSP_HOST_URL }} + SONAR_TOKEN: ${{ secrets.SONAR_BDSP_TOKEN }} + with: + args: >- + -Dsonar.projectKey=${{ github.event.repository.name }} + -Dsonar.projectVersion=${{ env.PROJECT_VERSION }} + -Dsonar.sources=src/main/java + -Dsonar.tests=src/test/java + -Dsonar.java.binaries=target/classes + -Dsonar.sourceEncoding=UTF-8 + -Dsonar.language=java + -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml + -Dsonar.java.libraries=./lib + + - name: SonarQube Quality Gate check + uses: sonarsource/sonarqube-quality-gate-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_BDSP_TOKEN }} + + - name: "Notify Slack: Failure (CI)" + if: ${{ failure() }} + uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main + with: + type: "failure" + webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} + diff --git a/.github/workflows/maven-ci-cd-teste.yaml b/.github/workflows/maven-ci-cd-teste.yaml index 5218631..e90d797 100644 --- a/.github/workflows/maven-ci-cd-teste.yaml +++ b/.github/workflows/maven-ci-cd-teste.yaml @@ -60,17 +60,9 @@ env: jobs: - Notify_Start: - runs-on: ubuntu-latest - steps: - - name: "Notify Slack: Start" - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "start" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} + CI: - needs: Notify_Start if: ${{ !inputs.is_production_branch }} runs-on: runner-pb-pefisa outputs: @@ -103,7 +95,7 @@ jobs: - name: Build and Push Docker image to GCR id: build_push - uses: platformbuilders/github-actions-bdsp-templates/build-push-image@main + uses: platformbuilders/github-actions-bdsp-templates/build-push-image@perf/improve-performance env: GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} @@ -123,99 +115,3 @@ jobs: path: ${{ github.event.repository.name }}-${{ steps.build_push.outputs.IMAGE_TAG }}-image-scanner-report.txt retention-days: 3 - - - name: "Notify Slack: Failure (CI)" - if: ${{ failure() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "failure" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} - - CD: - needs: CI - if: ${{ !inputs.is_production_branch && success() }} - runs-on: ubuntu-latest - steps: - - name: Kustomize Argo Manifests - uses: platformbuilders/github-actions-bdsp-templates/kustomize-argo-manifests@main - with: - image-tag: ${{ needs.CI.outputs.IMAGE_TAG }} - image-digest: ${{ needs.CI.outputs.IMAGE_DIGEST }} - github-token: ${{ secrets.TOKEN_GITHUB }} - repository-name: ${{ github.repository }} - env: - GH_TOKEN: ${{ secrets.TOKEN_GITHUB }} - - - - name: "Notify Slack: Success (CI/CD Non-Prod)" - if: ${{ success() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "success" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} - - - - name: "Notify Slack: Failure (CD)" - if: ${{ failure() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "failure" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} - - - CI_PRD: - needs: Notify_Start - - if: ${{ inputs.is_production_branch }} - runs-on: ubuntu-latest - outputs: - IMAGE_TAG: ${{ steps.get_image.outputs.IMAGE_TAG }} - IMAGE_DIGEST: ${{ steps.get_image.outputs.IMAGE_DIGEST }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ inputs.git_ref }} - - - name: Get image to GCR - id: get_image - uses: platformbuilders/github-actions-bdsp-templates/build-push-image@main - env: - GCP_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - - - name: "Notify Slack: Failure (CI_PRD)" - if: ${{ failure() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "failure" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} - - - CD_PRD: - needs: CI_PRD - if: ${{ inputs.is_production_branch && success() }} - runs-on: ubuntu-latest - steps: - - name: Kustomize Argo Manifests - uses: platformbuilders/github-actions-bdsp-templates/kustomize-argo-manifests@main - with: - image-tag: ${{ needs.CI_PRD.outputs.IMAGE_TAG }} - image-digest: ${{ needs.CI_PRD.outputs.IMAGE_DIGEST }} - github-token: ${{ secrets.TOKEN_GITHUB }} - repository-name: ${{ github.repository }} - env: - GH_TOKEN: ${{ secrets.TOKEN_GITHUB }} - - - name: "Notify Slack: Success (CI/CD PRD)" - if: ${{ success() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "success" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} - - - name: "Notify Slack: Failure (CD_PRD)" - if: ${{ failure() }} - uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main - with: - type: "failure" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/maven-ci-cd.yaml b/.github/workflows/maven-ci-cd.yaml index 5475f16..0474caa 100644 --- a/.github/workflows/maven-ci-cd.yaml +++ b/.github/workflows/maven-ci-cd.yaml @@ -69,8 +69,17 @@ jobs: type: "start" webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} + CI-Code-Quality: + #if: {{ !inputs.is_production_branch }} + uses: platformbuilders/github-actions-bdsp-templates/.github/workflows/code-quality.yaml@perf/improve-performance + secrets: inherit + with: + git_ref: ${{ github.ref }} + SONAR_BDSP_HOST_URL: ${{ inputs.SONAR_BDSP_HOST_URL }} + java_version: ${{ inputs.java_version }} + CI: - needs: Notify_Start + needs: [Notify_Start,CI-Code-Quality] if: ${{ !inputs.is_production_branch }} runs-on: ubuntu-latest outputs: @@ -101,101 +110,6 @@ jobs: run: | mvn clean package dependency:copy-dependencies -DoutputDirectory=./lib - - name: Check project existence in SonarQube - id: checkSonarProjectExistence - run: | - set -e - echo "Verificando se o projeto existe no SonarQube..." - - RESPONSE=$(curl --verbose --fail --location \ - "${{ inputs.SONAR_BDSP_HOST_URL }}/api/projects/search?projects=${{ github.event.repository.name }}" \ - --header "Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}") - - echo "$RESPONSE" - - FOUND_PROJECTS=$(echo "$RESPONSE" | jq -r '.paging.total' 2>/dev/null || echo "0") - - echo "FOUND_PROJECTS: $FOUND_PROJECTS" - - if [[ "$FOUND_PROJECTS" =~ ^[0-9]+$ && "$FOUND_PROJECTS" -eq 0 ]]; then - echo "exists=false" >> "$GITHUB_OUTPUT" - else - echo "exists=true" >> "$GITHUB_OUTPUT" - fi - - - name: Creating new project on SonarQube - if: steps.checkSonarProjectExistence.outputs.exists == 'false' - run: | - set -e - echo "Criando projeto no SonarQube..." - curl -f --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/projects/create' \ - --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'project=${{ github.event.repository.name }}' \ - --data-urlencode 'name=${{ github.event.repository.name }}' \ - --data-urlencode 'mainBranch=${{env.SONAR_MAIN_BRANCH}}' \ - --data-urlencode 'newCodeDefinitionType=${{env.SONAR_NEW_CODE_DEF_TYPE}}' \ - --data-urlencode 'visibility=${{env.SONAR_VISIBILITY}}' - - - name: Configuring quality gate - if: steps.checkSonarProjectExistence.outputs.exists == 'false' - run: | - set -e - echo "Atribuindo Quality Gate ao projeto..." - curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/qualitygates/select' \ - --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'gateName=${{env.SONAR_QUALITY_GATE}}' \ - --data-urlencode 'projectKey=${{ github.event.repository.name }}' - - - name: Configuring quality profile - if: steps.checkSonarProjectExistence.outputs.exists == 'false' - run: | - set -e - echo "Atribuindo Quality Profile..." - curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/qualityprofiles/add_project' \ - --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'language=${{env.SONAR_LANGUAGE}}' \ - --data-urlencode 'qualityProfile=${{env.SONAR_QUALITY_PROFILE}}' \ - --data-urlencode 'project=${{ github.event.repository.name }}' - - - name: Applying template permission - if: steps.checkSonarProjectExistence.outputs.exists == 'false' - run: | - set -e - echo "Atribuindo Permission Template..." - curl --location '${{ inputs.SONAR_BDSP_HOST_URL }}/api/permissions/apply_template' \ - --header 'Authorization: Bearer ${{ secrets.SONAR_BDSP_TOKEN }}' \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'projectKey=${{ github.event.repository.name }}' \ - --data-urlencode 'templateName=${{env.SONAR_PERMISSION_TEMPLATE}}' - - - name: Get project version - run: echo "PROJECT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV - - - name: SonarQube Scan - uses: sonarsource/sonarqube-scan-action@master - env: - SONAR_HOST_URL: ${{ inputs.SONAR_BDSP_HOST_URL }} - SONAR_TOKEN: ${{ secrets.SONAR_BDSP_TOKEN }} - with: - args: >- - -Dsonar.projectKey=${{ github.event.repository.name }} - -Dsonar.projectVersion=${{ env.PROJECT_VERSION }} - -Dsonar.sources=src/main/java - -Dsonar.tests=src/test/java - -Dsonar.java.binaries=target/classes - -Dsonar.sourceEncoding=UTF-8 - -Dsonar.language=java - -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml - -Dsonar.java.libraries=./lib - - - name: SonarQube Quality Gate check - uses: sonarsource/sonarqube-quality-gate-action@master - env: - SONAR_TOKEN: ${{ secrets.SONAR_BDSP_TOKEN }} - - name: Build and Push Docker image to GCR id: build_push uses: platformbuilders/github-actions-bdsp-templates/build-push-image@main @@ -313,4 +227,4 @@ jobs: uses: platformbuilders/github-actions-bdsp-templates/slack-notify@main with: type: "failure" - webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file + webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/build-push-image/Dockerfile b/build-push-image/Dockerfile index e6aa85f..4f8e60c 100644 --- a/build-push-image/Dockerfile +++ b/build-push-image/Dockerfile @@ -1,20 +1,13 @@ -FROM ubuntu:latest +FROM google/cloud-sdk:slim -RUN apt-get update && apt-get install -y \ - apt-transport-https \ - ca-certificates \ - gnupg \ - curl \ +RUN apt-get update && apt-get install -y --no-install-recommends \ git \ - docker.io \ jq \ - && curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \ - && echo "deb https://packages.cloud.google.com/apt cloud-sdk main" > /etc/apt/sources.list.d/google-cloud-sdk.list \ - && apt-get update \ - && apt-get install -y google-cloud-sdk \ + docker.io \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["/entrypoint.sh"] diff --git a/build-push-image/action.yaml b/build-push-image/action.yaml index d4e101f..df37441 100644 --- a/build-push-image/action.yaml +++ b/build-push-image/action.yaml @@ -2,9 +2,9 @@ name: 'Build and Push Docker Image to GCR' description: 'Builds and pushes a Docker image to Google Container Registry (GCR) based on the branch.' runs: using: 'docker' - image: 'Dockerfile' + image: 'docker://ghcr.io/platformbuilders/github-actions-bdsp-templates/build-push-image:latest' outputs: IMAGE_TAG: description: 'Tag da imagem Docker.' IMAGE_DIGEST: - description: 'Digest da imagem Docker.' \ No newline at end of file + description: 'Digest da imagem Docker.'