diff --git a/.github/workflows/anchore.yml b/.github/workflows/00_anchore.yml similarity index 100% rename from .github/workflows/anchore.yml rename to .github/workflows/00_anchore.yml diff --git a/.github/workflows/01_add_patch_label.yml b/.github/workflows/01_add_patch_label.yml new file mode 100644 index 0000000..41e5a82 --- /dev/null +++ b/.github/workflows/01_add_patch_label.yml @@ -0,0 +1,60 @@ +name: Add PATCH default label + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + pull_request_target: + branches: + - main + types: [ opened, reopened ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + add_patch_label: + runs-on: ubuntu-latest + name: Add default label + steps: + - name: Check user labels + id: check_user_labels + uses: actions/github-script@v6.3.3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var addPatch = "true"; + // retrieve label list + let labels = await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + + // verify if user have already added IGNORE-FOR-RELEASE, then skip add PATCH + // note: GitHub labels are added in .identity/03_github_environment.tf as github_issue_label resource + if (labels.data.find(label => label.name === 'ignore-for-release')){ + addPatch = "false"; + } + return addPatch; + result-encoding: string + + - name: Add PATCH label + if: ${{ steps.check_user_labels.outputs.result == 'true' }} + uses: pagopa/github-actions-template/default-label@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + label: 'patch' + + - name: Add comment + if: ${{ steps.check_user_labels.outputs.result == 'true' }} + uses: actions/github-script@v6.3.3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'The default action is to increase the `PATCH` number of `SEMVER`. Set `IGNORE-FOR-RELEASE` if you want to skip `SEMVER` bump. `BREAKING-CHANGE` and `NEW-RELEASE` must be run from GH Actions section manually.' + }); diff --git a/.github/workflows/01_assignee.yml b/.github/workflows/01_assignee.yml new file mode 100644 index 0000000..0611917 --- /dev/null +++ b/.github/workflows/01_assignee.yml @@ -0,0 +1,26 @@ +name: Auto Assign + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + pull_request_target: + branches: + - main + types: [ opened, reopened ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Assign Me + # You may pin to the exact commit or the version. + uses: kentaro-m/auto-assign-action@v1.2.1 + with: + configuration-path: '.github/auto_assign.yml' diff --git a/.github/workflows/02_check_pr.yml b/.github/workflows/02_check_pr.yml new file mode 100644 index 0000000..5608117 --- /dev/null +++ b/.github/workflows/02_check_pr.yml @@ -0,0 +1,113 @@ +name: Check PR + +# Controls when the workflow will run +on: + pull_request: + branches: + - main + types: [ opened, synchronize, labeled, unlabeled, reopened, edited ] + + +permissions: + pull-requests: write + + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + + check_labels: + name: Check Required Labels + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Verify PR Labels + if: ${{ !contains(github.event.pull_request.labels.*.name, 'patch') && !contains(github.event.pull_request.labels.*.name, 'ignore-for-release') }} + uses: actions/github-script@v6.3.3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + for (const comment of comments.data) { + if (comment.body.includes('This pull request does not contain a valid label')){ + github.rest.issues.deleteComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }) + } + } + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This pull request does not contain a valid label. Please add one of the following labels: `[patch, ignore-for-release]`' + }) + core.setFailed('Missing required labels') + + + check_format: + name: Check Format + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Formatting + id: format + continue-on-error: true + uses: axel-op/googlejavaformat-action@v3 + with: + args: "--set-exit-if-changed" + + - uses: actions/github-script@v6.3.3 + if: steps.format.outcome != 'success' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + console.log(context); + var comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + for (const comment of comments.data) { + console.log(comment); + if (comment.body.includes('Comment this PR with')){ + github.rest.issues.deleteComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }) + } + } + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Comment this PR with *update_code* to format the code. Consider to use pre-commit to format the code.' + }) + core.setFailed('Format your code.') + + + check_size: + runs-on: ubuntu-latest + name: Check Size + steps: + + - name: Dump GitHub context + run: echo $JSON + env: + JSON: ${{ toJSON(github) }} + + - name: Check PR Size + uses: pagopa/github-actions-template/check-pr-size@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + ignored_files: 'openapi.json' diff --git a/.github/workflows/03_code_review.yml b/.github/workflows/03_code_review.yml new file mode 100644 index 0000000..b61a944 --- /dev/null +++ b/.github/workflows/03_code_review.yml @@ -0,0 +1,46 @@ +name: Code Review + +# Controls when the workflow will run +on: + pull_request: + branches: + - main + types: + - opened + - synchronize + - reopened + push: + branches: + - main + + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + PROJECT_KEY: pagopa_pagopa-mocker + + +permissions: + id-token: write + contents: read + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + code-review: + name: Code Review + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Code Review + uses: pagopa/github-actions-template/maven-code-review@50aaf5cffa09d76b953e64a630bc9e0528a6d73b + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + sonar_token: ${{ secrets.SONAR_TOKEN }} + project_key: ${{env.PROJECT_KEY}} + coverage_exclusions: "**/config/*,**/*Mock*,**/models/**,**/entities/*" + cpd_exclusions: "**/models/**,**/entities/*" + java_distribution: "graalvm" + java_version: "17.0.7" diff --git a/.github/workflows/release_deploy.yml b/.github/workflows/04_release_deploy.yml similarity index 51% rename from .github/workflows/release_deploy.yml rename to .github/workflows/04_release_deploy.yml index f2e9eb9..c29f348 100644 --- a/.github/workflows/release_deploy.yml +++ b/.github/workflows/04_release_deploy.yml @@ -3,6 +3,8 @@ name: Release And Deploy # Controls when the workflow will run on: pull_request: + branches: + - main types: [ closed ] # Allows you to run this workflow manually from the Actions tab @@ -15,18 +17,28 @@ on: options: - dev - uat - - all - beta: + - prod + semver: required: false - type: boolean - description: deploy beta version on AKS - default: false - skip_release: - required: false - type: boolean - description: skip the release. Only deploy - default: false - + type: choice + description: Select the version + options: + - '' + - skip + - promote + - patch + - new_release + - breaking_change + + workflow_call: + inputs: + environment: + required: true + type: string + semver: + required: true + type: string + default: skip permissions: packages: write @@ -42,49 +54,20 @@ jobs: name: Setup runs-on: ubuntu-latest outputs: - semver: ${{ steps.get_semver.outputs.semver }} - environment: ${{ steps.get_env.outputs.environment }} + semver: ${{ steps.semver_setup.outputs.semver }} + environment: ${{ steps.semver_setup.outputs.environment }} steps: - - name: pull request rejected - if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged != true - run: | - echo "❌ PR was closed without a merge" - exit 1 - - # Set Semvar - - run: echo "SEMVER=patch" >> $GITHUB_ENV - - - if: ${{ (github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'breaking-change ')) }} - run: echo "SEMVER=major" >> $GITHUB_ENV - - - if: ${{ inputs.environment == 'uat' }} - run: echo "SEMVER=minor" >> $GITHUB_ENV - - - if: ${{ github.ref_name != 'main' }} - run: echo "SEMVER=buildNumber" >> $GITHUB_ENV - - - if: ${{ inputs.skip_release }} - run: echo "SEMVER=skip" >> $GITHUB_ENV - - - id: get_semver - name: Set Output - run: echo "semver=${{env.SEMVER}}" >> $GITHUB_OUTPUT - - # Set Environment - - run: echo "ENVIRNOMENT=${{ inputs.environment}}" >> $GITHUB_ENV - - - if: ${{ inputs.environment == null }} - run: echo "ENVIRNOMENT=dev" >> $GITHUB_ENV - - - id: get_env - name: Set Output - run: echo "environment=${{env.ENVIRNOMENT}}" >> $GITHUB_OUTPUT - + - name: Semver setup + id: semver_setup + uses: pagopa/github-actions-template/nodo5-semver-setup@89ce1bcaf0da44968cd4e72d297cc916df5a914d + with: + semver: ${{ inputs.semver }} release: + needs: [setup] name: Create a New Release runs-on: ubuntu-latest - needs: [setup] + if: ${{ needs.setup.outputs.semver != 'skip' }} outputs: version: ${{ steps.release.outputs.version }} steps: @@ -101,7 +84,7 @@ jobs: needs: [ setup, release ] name: Build and Push Docker Image runs-on: ubuntu-latest - if: ${{ inputs.semver != 'skip' }} + if: ${{ needs.setup.outputs.semver != 'skip' }} steps: - name: Build and Push id: semver @@ -117,9 +100,28 @@ jobs: if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} strategy: matrix: - environment: [ dev, uat ] - uses: ./.github/workflows/deploy_with_github_runner.yml + environment: [ dev, uat, prod ] + uses: ./.github/workflows/04h_deploy_with_github_runner.yml with: environment: ${{ matrix.environment }} target: ${{ needs.setup.outputs.environment }} secrets: inherit + +# notify: +# name: Notify +# needs: [ setup, release, deploy_aks ] +# runs-on: ubuntu-latest +# if: always() +# steps: +# - name: Report Status +# if: always() +# uses: ravsamhq/notify-slack-action@v2 +# with: +# status: ${{ needs.deploy_aks.result }} +# token: ${{ secrets.GITHUB_TOKEN }} +# notification_title: 'New Release on ${{ needs.setup.outputs.environment }} for ${{ needs.release.outputs.version }} has {status_message}' +# message_format: '{emoji} <{run_url}|{workflow}> {status_message} in <{repo_url}|{repo}>' +# footer: 'Linked to <{workflow_url}| workflow file>' +# icon_success: ':white_check_mark:' +# env: +# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/deploy_with_github_runner.yml b/.github/workflows/04h_deploy_with_github_runner.yml similarity index 97% rename from .github/workflows/deploy_with_github_runner.yml rename to .github/workflows/04h_deploy_with_github_runner.yml index b98b88b..710a96d 100644 --- a/.github/workflows/deploy_with_github_runner.yml +++ b/.github/workflows/04h_deploy_with_github_runner.yml @@ -42,7 +42,6 @@ jobs: container_app_environment_name: ${{ vars.CONTAINER_APP_ENVIRONMENT_NAME }} resource_group_name: ${{ vars.CONTAINER_APP_ENVIRONMENT_RESOURCE_GROUP_NAME }} # RG of the runner pat_token: ${{ secrets.BOT_TOKEN_GITHUB }} - self_hosted_runner_image_tag: "v1.4.1" deploy: needs: [ create_runner ] @@ -59,7 +58,7 @@ jobs: subscription_id: ${{ secrets.SUBSCRIPTION_ID }} tenant_id: ${{ secrets.TENANT_ID }} env: ${{ inputs.environment }} - namespace: ${{ env.NAMESPACE }} + namespace: ${{ vars.NAMESPACE }} cluster_name: ${{ vars.CLUSTER_NAME }} resource_group: ${{ vars.CLUSTER_RESOURCE_GROUP }} app_name: ${{ env.APP_NAME }} diff --git a/.github/workflows/integration_test.yml b/.github/workflows/05_integration_test.yml similarity index 100% rename from .github/workflows/integration_test.yml rename to .github/workflows/05_integration_test.yml diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml deleted file mode 100644 index 953df7e..0000000 --- a/.github/workflows/check_pr.yml +++ /dev/null @@ -1,190 +0,0 @@ -name: Check PR - -# Controls when the workflow will run -on: - pull_request: - branches: - - main - types: [ opened, synchronize, labeled, unlabeled, reopened, edited ] - - -permissions: - pull-requests: write - - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - auto_assign: - name: Auto Assign - - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - name: Assign Me - # You may pin to the exact commit or the version. - uses: kentaro-m/auto-assign-action@v1.2.1 - with: - configuration-path: '.github/auto_assign.yml' - - check_format: - name: Check Format - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Formatting - id: format - continue-on-error: true - uses: axel-op/googlejavaformat-action@v3 - with: - args: "--set-exit-if-changed" - - - uses: actions/github-script@v6.3.3 - if: steps.format.outcome != 'success' - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - console.log(context); - var comments = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }); - for (const comment of comments.data) { - console.log(comment); - if (comment.body.includes('Comment this PR with')){ - github.rest.issues.deleteComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: comment.id - }) - } - } - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: 'Comment this PR with *update_code* to update `openapi.json` and format the code. Consider to use pre-commit to format the code.' - }) - core.setFailed('Format your code.') - - check_size: - runs-on: ubuntu-latest - name: Check Size - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Check Size - uses: actions/github-script@v6.3.3 - env: - IGNORED_FILES: openapi.json, openapi-node.json - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const additions = context.payload.pull_request.additions || 0 - const deletions = context.payload.pull_request.deletions || 0 - var changes = additions + deletions - console.log('additions: '+additions+' + deletions: '+deletions+ ' = total changes: ' + changes); - - const { IGNORED_FILES } = process.env - const ignored_files = IGNORED_FILES.trim().split(',').filter(word => word.length > 0); - if (ignored_files.length > 0){ - var ignored = 0 - const execSync = require('child_process').execSync; - for (const file of IGNORED_FILES.trim().split(',')) { - - const ignored_additions_str = execSync('git --no-pager diff --numstat origin/main..origin/${{ github.head_ref}} | grep ' + file + ' | cut -f 1', { encoding: 'utf-8' }) - const ignored_deletions_str = execSync('git --no-pager diff --numstat origin/main..origin/${{ github.head_ref}} | grep ' + file + ' | cut -f 2', { encoding: 'utf-8' }) - - const ignored_additions = ignored_additions_str.split('\n').map(elem=> parseInt(elem || 0)).reduce( - (accumulator, currentValue) => accumulator + currentValue, - 0); - const ignored_deletions = ignored_deletions_str.split('\n').map(elem=> parseInt(elem || 0)).reduce( - (accumulator, currentValue) => accumulator + currentValue, - 0); - - ignored += ignored_additions + ignored_deletions; - } - changes -= ignored - console.log('ignored lines: ' + ignored + ' , consider changes: ' + changes); - } - - if (changes < 200){ - github.rest.issues.addLabels({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['size/small'] - }) - - - var labels = await github.rest.issues.listLabelsOnIssue({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }); - - if (labels.data.find(label => label.name == 'size/large')){ - github.rest.issues.removeLabel({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - name: 'size/large' - }) - } - } - - if (changes > 400){ - github.rest.issues.addLabels({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['size/large'] - }) - - var comments = await github.rest.issues.listComments({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }); - for (const comment of comments.data) { - if (comment.body.includes('This PR exceeds the recommended size')){ - github.rest.issues.deleteComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: comment.id - }) - } - } - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: 'This PR exceeds the recommended size of 400 lines. Please make sure you are NOT addressing multiple issues with one PR. _Note this PR might be rejected due to its size._' - }) - - var labels = await github.rest.issues.listLabelsOnIssue({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo - }); - - if (labels.data.find(label => label.name == 'size/small')){ - github.rest.issues.removeLabel({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - name: 'size/small' - }) - } - - } - diff --git a/.github/workflows/code_review.yml b/.github/workflows/code_review.yml deleted file mode 100644 index a04c95c..0000000 --- a/.github/workflows/code_review.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: Code Review - -# Controls when the workflow will run -on: - pull_request: - branches: - - main - types: - - opened - - synchronize - - reopened - push: - branches: - - main - - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -env: - PROJECT_KEY: pagopa_pagopa-mocker - -permissions: - id-token: write - contents: read - deployments: write - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - code-review: - name: Code Review - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - name: Code Review - uses: pagopa/github-actions-template/maven-code-review@v1.4.2 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - sonar_token: ${{ secrets.SONAR_TOKEN }} - project_key: ${{env.PROJECT_KEY}} - coverage_exclusions: "**/config/*,**/controller/*,**/model/**,**/entity/*" - cpd_exclusions: "**/model/**,**/entity/*" - - smoke-test: - name: Smoke Test - runs-on: ubuntu-latest - environment: - name: dev - steps: - - name: Checkout - id: checkout - uses: actions/checkout@1f9a0c22da41e6ebfa534300ef656657ea2c6707 - - - name: Login - id: login - # from https://github.com/Azure/login/commits/master - uses: azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 - with: - client-id: ${{ secrets.CLIENT_ID }} - tenant-id: ${{ secrets.TENANT_ID }} - subscription-id: ${{ secrets.SUBSCRIPTION_ID }} - - - name: Run Service on Docker - shell: bash - id: run_service_docker - run: | - cd ./docker - chmod +x ./run_docker.sh - ./run_docker.sh local - - - name: Run Integration Tests - shell: bash - id: run_integration_test - run: | - export SUBKEY=${{ secrets.SUBKEY }} - export CANARY=${{ inputs.canary }} - export CUCUMBER_PUBLISH_TOKEN=${{ secrets.CUCUMBER_PUBLISH_TOKEN }} - - cd ./integration-test - chmod +x ./run_integration_test.sh - ./run_integration_test.sh local - - - delete_github_deployments: - runs-on: ubuntu-latest - needs: smoke-test - if: ${{ always() }} - steps: - - name: Delete Previous deployments - uses: actions/github-script@v6 - env: - SHA_HEAD: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.sha) || github.sha}} - with: - script: | - const { SHA_HEAD } = process.env - - const deployments = await github.rest.repos.listDeployments({ - owner: context.repo.owner, - repo: context.repo.repo, - sha: SHA_HEAD - }); - await Promise.all( - deployments.data.map(async (deployment) => { - await github.rest.repos.createDeploymentStatus({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: deployment.id, - state: 'inactive' - }); - return github.rest.repos.deleteDeployment({ - owner: context.repo.owner, - repo: context.repo.repo, - deployment_id: deployment.id - }); - }) - ); diff --git a/.github/workflows/update_code.yml b/.github/workflows/update_code.yml deleted file mode 100644 index e254b35..0000000 --- a/.github/workflows/update_code.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Update Code - -on: - issue_comment: - types: [created, edited] - - -permissions: - contents: write - pull-requests: write - issues: write - -jobs: - update: - name: Update Openapi and Formatting - runs-on: ubuntu-latest - if: ${{ contains(github.event.comment.body, 'update_code') }} - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ secrets.BOT_TOKEN_GITHUB }} - - - name: Checkout Pull Request - run: hub pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - - name: Run Service on Docker - shell: bash - run: | - cd ./docker - chmod +x ./run_docker.sh - ./run_docker.sh local