name: Update rule coverage on: schedule: - cron: '17 2 * * *' workflow_dispatch: # When manually triggered from a non-default branch, the results will not be pushed jobs: update_coverage: runs-on: ubuntu-latest permissions: id-token: write # required by SonarSource/vault-action-wrapper contents: write actions: write # required by andymckay/cancel-action env: TMP_BRANCH: temporary/coverage_update steps: - name: 'get secrets' id: secrets uses: SonarSource/vault-action-wrapper@v3 with: secrets: | development/github/token/SonarSource-rspec-coverage token | coverage_github_token; development/kv/data/slack token | slack_token; - uses: actions/checkout@v4 with: persist-credentials: true fetch-depth: 0 path: 'rspec' token: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }} ref: 'master' - uses: actions/setup-python@v4 with: python-version: '3.9' - name: 'Install Pipenv' run: pip install pipenv - name: 'Install coverage script dependencies' working-directory: 'rspec/rspec-tools' run: | pipenv --python python3.9 install - name: 'Regenerate coverage information' env: GITHUB_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }} id: gen-coverage working-directory: 'rspec/rspec-tools' run: | pipenv run rspec-tools update-coverage --rulesdir ../rules mv ./covered_rules.json ../frontend/public/covered_rules.json if git diff --exit-code ../frontend/public/covered_rules.json; then echo "new_coverage=false" >> "$GITHUB_OUTPUT" else echo "new_coverage=true" >> "$GITHUB_OUTPUT" fi - name: 'Cancel if coverage did not change' if: steps.gen-coverage.outputs.new_coverage != 'true' uses: andymckay/cancel-action@0.2 - name: 'Push the updated coverage file to a new branch' id: create-temp-branch if: steps.gen-coverage.outputs.new_coverage == 'true' working-directory: 'rspec' run: | git config --global user.name "SonarTech" git config --global user.email "sonartech@sonarsource.com" git checkout -b $TMP_BRANCH git add frontend/public/covered_rules.json git commit -m "update coverage information" git push --force-with-lease origin $TMP_BRANCH - name: 'Create a PR' id: create-github-pr working-directory: 'rspec' env: GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }} run: | PR_URL=$(gh pr create --head ${{ env.TMP_BRANCH }} --title "Update coverage information" --body "" --label "rspec system") gh pr merge $PR_URL - name: 'Wait until the PR is merged' id: wait-for-pr-to-merge env: GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }} working-directory: 'rspec' run: | set -ueo pipefail # Implicitly referring to the PR corresponding to current branch # Set timeout (20 minutes in seconds) TIMEOUT=1200 # seconds START_TIME=$(date +%s) INTERVAL=20 # seconds while true; do # Check if the PR is merged PR_STATE=$(gh pr view --json state,mergedAt -q '.state') MERGED_AT=$(gh pr view --json state,mergedAt -q '.mergedAt') if [[ "${PR_STATE}" == "MERGED" ]]; then echo "PR merged at: $MERGED_AT" exit 0 fi echo "PR state is ${PR_STATE}" # Check for timeout CURRENT_TIME=$(date +%s) ELAPSED_TIME=$((CURRENT_TIME - START_TIME)) if [[ "${ELAPSED_TIME}" -gt "${TIMEOUT}" ]]; then echo "Timeout waiting for PR to merge." exit 1 fi # Wait for $INTERVAL seconds before checking again sleep "$INTERVAL" done - name: 'Close PR and delete branch upon failure to merge' if: ${{ failure() }} env: GH_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).coverage_github_token }} working-directory: 'rspec' run: | PR_URL=$(gh pr view --json url --jq '.url') gh pr close "$PR_URL" --delete-branch - name: 'Notify on slack about the failure' if: ${{ failure() }} env: SLACK_API_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).slack_token }} working-directory: 'rspec/rspec-tools' run: | pipenv run rspec-tools notify-failure-on-slack \ --message "ERROR: failed to update rule coverage. See https://github.com/SonarSource/rspec/actions/runs/$GITHUB_RUN_ID" \ --channel team-analysis-rspec