name: '[CI/CD] CI Pipeline' on: # rebuild any PRs and main branch changes pull_request_target: types: - synchronize - labeled branches: - main - bitnami:main permissions: issues: write pull-requests: write statuses: write env: CSP_API_URL: https://console.cloud.vmware.com CSP_API_TOKEN: ${{ secrets.CSP_API_TOKEN }} VIB_PUBLIC_URL: https://cp.bromelia.vmware.com # Avoid concurrency over the same PR concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} jobs: get-containers: runs-on: ubuntu-latest name: Get modified containers if: | github.event.pull_request.state != 'closed' && ( contains(github.event.pull_request.labels.*.name, 'verify') || (github.event.action == 'labeled' && github.event.label.name == 'verify') ) outputs: result: ${{ steps.get-containers.outputs.result }} containers: ${{ steps.get-containers.outputs.containers }} steps: - id: get-containers name: Get modified containers run: | # Using the Github API to detect the files changed as git merge-base stops working when the branch is behind # and jitterbit/get-changed-files does not support pull_request_target URL="https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" files_changed_data=$(curl -s --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -X GET -G "$URL") files_changed="$(echo $files_changed_data | jq -r '.[] | .filename')" # Adding || true to avoid "Process exited with code 1" errors flavors=($(echo "$files_changed" | xargs dirname | grep -o "^bitnami/[^/]*/[^/]*/[^/]*" | sort | uniq || true)) assets=($(echo "$files_changed" | xargs dirname | sed -nr "s|bitnami/([^/]*)/.*|\1|p" | sort | uniq || true)) non_readme_files=$(echo "$files_changed" | grep -vc "\.md" || true) if [[ "$non_readme_files" -le "0" ]]; then # The only changes are .md files -> SKIP echo "result=skip" >> $GITHUB_OUTPUT elif [[ "${#assets[@]}" -ne "1" ]]; then echo "Changes should affect to only one asset. You are currently modifying: ${assets[@]}" echo "result=skip" >> $GITHUB_OUTPUT else containers_json=$(printf "%s\n" "${flavors[@]}" | jq -R . | jq -cs .) echo "result=ok" >> $GITHUB_OUTPUT echo "containers=${containers_json}" >> $GITHUB_OUTPUT fi vib-verify: runs-on: ubuntu-latest needs: get-containers if: ${{ needs.get-containers.outputs.result == 'ok' }} name: VIB Verify continue-on-error: false strategy: fail-fast: false max-parallel: 2 matrix: container: ${{ fromJSON(needs.get-containers.outputs.containers) }} steps: - uses: actions/checkout@v3 name: Checkout Repository with: # Full history is not required anymore fetch-depth: 1 # labeled events trigger the event with the latest commit in main ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - id: get-container-metadata name: Get image tag and container name run: | if [[ -d "${{ matrix.container }}" ]]; then name="$(echo "${{ matrix.container }}" | awk -F '/' '{print $2}')" tag="" if [[ "${{ github.event.pull_request.user.login }}" == "bitnami-bot" ]]; then tag="$(grep -oE "org.opencontainers.image.ref.name=\".+\"" ${{ matrix.container }}/Dockerfile | sed -nr "s|org.opencontainers.image.ref.name=\"(.+)\"|\1|p")" else # Build a tag based on current RUN number tag="$(echo "${{ matrix.container }}" | awk -F '/' -v run_number="${GITHUB_RUN_NUMBER}" '{printf "%s-rc.%s", $3, run_number}')" fi if [[ -z "${tag}" ]]; then echo "No tag found for: ${{ matrix.container }}" exit 1 else echo "tag=${tag}" >> $GITHUB_OUTPUT echo "name=${name}" >> $GITHUB_OUTPUT echo "result=ok" >> $GITHUB_OUTPUT fi else # Container folder doesn't exists we are assuming a deprecation echo "result=skip" >> $GITHUB_OUTPUT fi - uses: vmware-labs/vmware-image-builder-action@main name: Verify if: ${{ steps.get-container-metadata.outputs.result == 'ok' }} with: pipeline: ${{ steps.get-container-metadata.outputs.name }}/vib-verify.json env: # Path with docker resources VIB_ENV_PATH: ${{ matrix.container }} # Container name VIB_ENV_CONTAINER: ${{ steps.get-container-metadata.outputs.name }} VIB_ENV_TAG: ${{ steps.get-container-metadata.outputs.tag }} verification-summary: # Ensure all containers passed the verification runs-on: ubuntu-latest name: Check Matrix Outcome needs: - get-containers - vib-verify outputs: result: ${{ steps.get-status.outputs.result }} if: ${{ always() }} steps: - id: get-status name: Check Status uses: actions/github-script@v6 with: result-encoding: string script: | state = 'success' description = 'Well done! Everything looks good. Please wait for the Bitnami Team review.' if ("${{ needs.get-containers.result }}" != "success" ) { description = "If you've just created this PR, don't worry about this message. The Bitnami Team has to review it and make the verification possible." core.warning(description) state = 'pending' } else if ("${{ needs.get-containers.outputs.result }}" == "skip" ) { description = "It seems these changes don't involve any container" core.warning(description) } else if ("${{ needs.vib-verify.result }}" != "success" ) { description = "Please review previous jobs to get more information" core.error(description) state = 'error' } else { core.notice(description) } try { await github.rest.repos.createCommitStatus({ context: `${context.workflow} / Verification Summary (${context.eventName})`, owner: context.payload.repository.owner.login, repo: context.payload.repository.name, sha: context.payload.pull_request.head.sha, target_url: `${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`, description: description, state: state }) core.info(`Updated build status: ${state}`) } catch (error) { core.setFailed(error.message) } return state auto-pr-review: runs-on: ubuntu-latest name: Reviewal for automated PRs needs: verification-summary # This job will be executed when the PR was created by bitnami-bot and it has the 'auto-merge' label if: | always() && contains(github.event.pull_request.labels.*.name, 'auto-merge') && github.event.pull_request.user.login == 'bitnami-bot' steps: # Approve the CI's PR if the 'VIB Verify' job succeeded # Approved by the 'github-actions' user; a PR can't be approved by its author - name: PR Approval if: ${{ needs.verification-summary.outputs.result == 'success' }} uses: hmarr/auto-approve-action@v3.0.0 with: pull-request-number: ${{ github.event.number }} - name: Merge id: merge if: ${{ needs.verification-summary.outputs.result == 'success' }} uses: actions/github-script@v6 with: result-encoding: string retries: 3 # Necessary to trigger CD workflows github-token: ${{ secrets.BITNAMI_BOT_TOKEN }} script: | github.rest.pulls.merge({ pull_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, merge_method: 'squash' }) # If the CI did not succeed ('VIB Verify' failed or skipped), # post a comment on the PR and assign a maintainer agent to review it - name: Manual review required if: ${{ always() && (needs.verification-summary.outputs.result != 'success' || steps.merge.outcome != 'success') }} uses: peter-evans/create-or-update-comment@v2.0.0 with: issue-number: ${{ github.event.number }} # Necessary to trigger support workflows token: ${{ secrets.BITNAMI_BOT_TOKEN }} body: | There has been an error during the automated release process. Manual revision is now required. Please check the related [action_run#${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more information.