diff --git a/codecov.yml b/.github/codecov.yml similarity index 100% rename from codecov.yml rename to .github/codecov.yml diff --git a/.github/workflows/slack_notifier_merged.yaml b/.github/workflows/slack_notifier_merged.yml similarity index 100% rename from .github/workflows/slack_notifier_merged.yaml rename to .github/workflows/slack_notifier_merged.yml diff --git a/.github/workflows/slack_notifier_open_pulls.yml b/.github/workflows/slack_notifier_open_pulls.yml new file mode 100644 index 00000000..5615542e --- /dev/null +++ b/.github/workflows/slack_notifier_open_pulls.yml @@ -0,0 +1,57 @@ +name: "post open pulls to slack" + +on: + schedule: + # Run daily at 13:00 Eastern / 10:00 Pacific + - cron: "0 17 * * *" + + +jobs: + list-open-prs: + runs-on: ubuntu-latest + permissions: + pull-requests: read + issues: read + + steps: + - name: Check out the repository + uses: actions/checkout@v3 + + - name: List open pull requests + id: list_prs + run: > + PR_LIST=$(scripts/open_pulls.sh) + + MSG=":code-review: Open Pull Requests\n\n" + + while IFS= read -r line; do + MSG+="$line\n" + done < <(echo "$PR_LIST" | jq -r '.[] | " - <\(.html_url)|\(.title)> opened by \(.user) \(.time_since) days ago"') + + echo "MSG=$MSG" >> $GITHUB_ENV + echo "PR_LIST=$PR_LIST" >> $GITHUB_ENV + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO: ${{ github.repository }} + + - name: Post to Slack + id: slack + uses: slackapi/slack-github-action@v1.27.0 + if: ${{ env.PR_LIST != '[]' }} + with: + payload: | + { + "text": "${{ env.MSG }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ env.MSG }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/.github/workflows/slack_notifier_review.yaml b/.github/workflows/slack_notifier_review.yml similarity index 66% rename from .github/workflows/slack_notifier_review.yaml rename to .github/workflows/slack_notifier_review.yml index 066fdb21..0e7177ce 100644 --- a/.github/workflows/slack_notifier_review.yaml +++ b/.github/workflows/slack_notifier_review.yml @@ -22,13 +22,13 @@ jobs: with: payload: | { - "text": ":code-review: Pull request ready for review by ${{ github.event.pull_request.user.login }}\n\n<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>", + "text": ":pr-open: Pull request ready for review by ${{ github.event.pull_request.user.login }}\n\n<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": ":code-review: Pull request ready for review by ${{ github.event.pull_request.user.login }}\n\n<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>" + "text": ":pr-open: Pull request ready for review by ${{ github.event.pull_request.user.login }}\n\n<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>" } } ] diff --git a/scripts/open_pulls.sh b/scripts/open_pulls.sh new file mode 100755 index 00000000..ab3f53bf --- /dev/null +++ b/scripts/open_pulls.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# This script lists all open pull requests for this repository. +# +# Usage: open_pulls.sh +# Requires: curl, jq + +set -e + +cd "$(dirname "$0")/.." + +# check if the GITHUB_TOKEN environment variable is set +if [ -z "$GITHUB_TOKEN" ]; then + echo "Missing environment variable: GITHUB_TOKEN" + exit 1 +fi + +if [ -z "$GITHUB_REPO" ]; then + REMOTE=$(git config --get remote.origin.url | sed -E 's#git@github.com:(.*)\.git#\1#') + GITHUB_REPO="$(echo $REMOTE | cut -d'/' -f1)/$(echo $REMOTE | cut -d'/' -f2)" +fi +# set the URL to the GitHub API +URL="https://api.github.com/repos/${GITHUB_REPO}" + +# create function to call GH API, the first argument is the endpoint +gh_api() { + curl --silent -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" ${URL}/$1 +} + +# List all open non-draft pull requests, and reduce to key fields +pr_list=$(gh_api pulls?state=open | jq -r 'map(select(.draft == false))' | jq '[.[] | {title, number, user: .user.login, html_url, created_at}]') + +# For each PR, get the timestamp of the ready_for_review event using the timeline API +# create an array of JSON objects +results="" +while IFS= read -r pr; do + number=$(echo "$pr" | jq -r '.number') + # get the timestamp of the ready_for_review event + ready_for_review=$(gh_api issues/${number}/timeline | jq -r 'map(select(.event == "ready_for_review")) | .[0].created_at') + # calculate the number of days since the PR was ready for review + # only calculate if ready_for_review does not equal "null" + if [ "$ready_for_review" == "null" ]; then + ready_for_review=$(echo $pr | jq -r '.created_at') + fi + time_since=$((($(date +%s) - $(date -d "$ready_for_review" +%s)) / 86400)) + # add the time_since field to the JSON object + pr=$(echo "$pr" | jq ". + {time_since: $time_since}") + if [ -z "$results" ]; then + results="$pr" + else + results="$results, $pr" + fi +done < <(echo "$pr_list" | jq -c '.[]') +# output the results as a JSON array +echo "[$results]" | jq .