diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4c80518b..cf1f835e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: "nuget" directory: "/" schedule: - interval: "monthly" + interval: "daily" labels: - "dependency update" commit-message: diff --git a/.github/workflows/notify-dependabot.yml b/.github/workflows/notify-dependabot.yml new file mode 100644 index 00000000..60219096 --- /dev/null +++ b/.github/workflows/notify-dependabot.yml @@ -0,0 +1,124 @@ +name: Dependabot Notifications + +on: + workflow_run: + workflows: ["*"] + types: + - completed + +jobs: + notify-checks: + runs-on: ubuntu-latest + + if: github.actor == 'dependabot[bot]' + steps: + - name: Get PR Information + id: get-pr-info + uses: actions/github-script@v6 + with: + script: | + const { owner, repo } = context.repo; + const run = context.payload.workflow_run; + + // Get PR directly from the workflow run's head SHA + const response = await github.rest.repos.listPullRequestsAssociatedWithCommit({ + owner, + repo, + commit_sha: run.head_sha + }); + + const pr = response.data[0]; // Get the first associated PR + + if (pr) { + core.exportVariable('PR_TITLE', pr.title); + core.exportVariable('PR_AUTHOR', pr.user.login); + core.exportVariable('PR_LINK', pr.html_url); + core.exportVariable('PR_NUMBER', pr.number.toString()); + } else { + core.exportVariable('PR_TITLE', 'Unknown'); + core.exportVariable('PR_AUTHOR', context.actor); + core.exportVariable('PR_LINK', `https://github.com/${owner}/${repo}/pulls`); + core.exportVariable('PR_NUMBER', ''); + } + + // Get check runs for this commit + const checkRuns = await github.rest.checks.listForRef({ + owner, + repo, + ref: run.head_sha + }); + + // Count different check conclusions + const stats = checkRuns.data.check_runs.reduce((acc, check) => { + acc[check.conclusion] = (acc[check.conclusion] || 0) + 1; + return acc; + }, {}); + + // Create status summary + const summary = Object.entries(stats) + .map(([status, count]) => `${count} ${status}`) + .join(', '); + + core.exportVariable('CHECKS_SUMMARY', summary); + + // Determine overall status + const hasFailures = stats.failure > 0; + const hasSuccess = stats.success > 0; + const hasCancelled = stats.cancelled > 0; + + let overallStatus; + if (hasFailures) { + overallStatus = 'failure'; + } else if (hasCancelled && !hasSuccess) { + overallStatus = 'cancelled'; + } else if (hasSuccess) { + overallStatus = 'success'; + } else { + overallStatus = 'unknown'; + } + + // Only set status if this is the last workflow to complete + const incompleteRuns = await github.rest.actions.listWorkflowRunsForRepo({ + owner, + repo, + head_sha: run.head_sha, + status: 'in_progress' + }); + + if (incompleteRuns.data.total_count === 0) { + core.exportVariable('ALL_CHECKS_STATUS', overallStatus); + core.exportVariable('SHOULD_NOTIFY', 'true'); + + // If checks failed and PR exists, close it + if ((overallStatus === 'failure' || overallStatus === 'cancelled') && pr) { + await github.rest.pulls.update({ + owner, + repo, + pull_number: pr.number, + state: 'closed' + }); + + // Add comment explaining why PR was closed + await github.rest.issues.createComment({ + owner, + repo, + issue_number: pr.number, + body: `This PR was automatically closed because some checks failed.\nStatus Summary: ${summary}` + }); + } + } else { + core.exportVariable('SHOULD_NOTIFY', 'false'); + } + + - name: Send Slack Notification for Success + if: env.SHOULD_NOTIFY == 'true' && env.ALL_CHECKS_STATUS == 'success' + uses: slackapi/slack-github-action@v1.25.0 + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + with: + payload: | + { + "text": "Repository: ${{ github.repository }}\nTitle: ${{ env.PR_TITLE }}\nAuthor: ${{ env.PR_AUTHOR }}\nLink: ${{ env.PR_LINK }}\nStatus Summary: ${{ env.CHECKS_SUMMARY }}", + "username": "PR Checks Monitor", + "icon_emoji": ":robot_face:" + } diff --git a/APIMatic.Core/APIMatic.Core.csproj b/APIMatic.Core/APIMatic.Core.csproj index e951f270..02d37fb2 100644 --- a/APIMatic.Core/APIMatic.Core.csproj +++ b/APIMatic.Core/APIMatic.Core.csproj @@ -38,7 +38,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - +