### GitHub Actions
- GitHub actions workflow to add at `.github/workflows/monthly-report.yml`
```yaml
name: github-monthly-report
on:
workflow_dispatch:
inputs:
monthstart:
required: true
default: '2024-xx-01'
monthend:
required: true
default: '2024-xx-31'
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
ORG: 'example'
REPO: 'example'
API_URL_PREFIX: 'https://api.github.com'
MONTH_START: ${{ github.event.inputs.monthstart }}
MONTH_END: ${{ github.event.inputs.monthend }}
jobs:
github-monthly-report:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: "Pull data from Github"
shell: bash
run: |
./apps/github-issues.sh
- name: "Send file output.txt to discord channel"
uses: sinshutu/upload-to-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_MONTHLY_REPORT }}
with:
args: output.txt issues.json
```
### Bash script calling GitHub API
- Bash file to add into repo at `./apps/github-issues.sh`
```bash
#!/bin/bash
set -euo pipefail
# debug mode
# set -x
###
## GLOBAL VARIABLES
###
GITHUB_TOKEN=${GITHUB_TOKEN:-''}
ORG=${ORG:-''}
REPO=${REPO:-''}
API_URL_PREFIX=${API_URL_PREFIX:-'https://api.github.com'}
MONTH_START=${MONTH_START:-'2022-03-01'}
MONTH_END=${MONTH_END:-'2022-03-31'}
EVENT_START=$(date --date="180 days ago" +%Y-%m-%d)
EVENT_END=$(date --date="30 days" +%Y-%m-%d)
get_public_pagination () {
# Github limits to 100 results per query, so we need to break up the results into 100 result chunks. We do this by breaking it up into pages
public_pages=$(curl -g -H "Authorization: token ${GITHUB_TOKEN}" -I "${API_URL_PREFIX}/repos/${ORG}/${REPO}/issues?state=all&labels=Linked%20[AC]&per_page=100" | grep -Eo '&page=[0-9]+' | grep -Eo '[0-9]+' | tail -1;)
echo "${public_pages:-1}"
}
limit_public_pagination () {
# Create sequence of pages
seq "$(get_public_pagination)"
}
repo_issues () {
# Iterate through all pages in the sequence
for PAGE in $(limit_public_pagination); do
# Filter through results and return on issues within the date range, sort by the issue number
for i in $(curl -g -H "Authorization: token ${GITHUB_TOKEN}" -s "${API_URL_PREFIX}/repos/${ORG}/${REPO}/issues?state=all&labels=Linked%20[AC]&page=${PAGE}&per_page=100" | jq -r 'map(select(.created_at | . >= "'"${EVENT_START}"'T00:00" and . <= "'"${EVENT_END}"'T23:59")) | sort_by(.number) | .[] | .number'); do
# Capture the event date from the timeline api
EVENT_DATE=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s "${API_URL_PREFIX}/repos/${ORG}/${REPO}/issues/${i}/timeline" -H "Accept: application/vnd.github.mockingbird-preview+json" | jq -r 'map(select(.created_at | . >= "'"${MONTH_START}"'T00:00" and . <= "'"${MONTH_END}"'T23:59")) | .[] | select(.label.name=="Linked [AC]")')
# check if the response from the event date is empty
if [ "${EVENT_DATE}" != "null" ] && [ "${EVENT_DATE}" != "[]" ] && [ "${EVENT_DATE}" != "" ]; then
# Capture the data from each filtered issue into a variable
ISSUE_PAYLOAD=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s "${API_URL_PREFIX}/repos/${ORG}/${REPO}/issues/${i}" -H "Accept: application/vnd.github.mercy-preview+json")
# Capture the data from each filtered issue from the timeline api
ISSUE_TIMELINE_PAYLOAD=$(curl -H "Authorization: token ${GITHUB_TOKEN}" -s "${API_URL_PREFIX}/repos/${ORG}/${REPO}/issues/${i}/timeline" -H "Accept: application/vnd.github.mockingbird-preview+json" | jq -r '.[] | select(.label.name=="Linked [AC]")')
# Capture who reported the issue into a variable
ISSUE_AUTHOR=$(echo "$ISSUE_PAYLOAD" | jq -r .user.login)
# Capture the url for the issue into a variable
ISSUE_HTML_URL=$(echo "$ISSUE_PAYLOAD" | jq -r .html_url)
# Capture who applied the linked label
ISSUE_TIMELINE_LABELED_BY=$(echo "$ISSUE_TIMELINE_PAYLOAD" | jq -s 'first(.[]| .actor.login)' | jq -r)
# output data from variables into a json like file for later processing
cat >> issues.json << EOF
{
"author": "${ISSUE_AUTHOR}",
"issue_url": "${ISSUE_HTML_URL}",
"contributor": "${ISSUE_TIMELINE_LABELED_BY}"
}
EOF
echo -e "issue has been processed ""${i}"""
fi
done
done
}
author_json () {
# Process data about the issue creator
AUTHORS=$(cat issues.json| jq -r '.author' | sort | uniq -c | awk -F " " '{print "{\"author\":""\""$2"\""",\"count\":" $1"}"}' | jq -r .author)
echo -e "Issue Reporters" >> output.txt
# Iterate through all issue creators found in the temp json like file
for AUTHOR in ${AUTHORS}; do
# Capture the issue creator data into a variable
TEST_PAYLOAD=$(cat issues.json| jq -r '.author' | sort | uniq -c | awk -F " " '{print "{\"author\":""\""$2"\""",\"count\":" $1"}"}' | jq -r .)
# Capture the issue creator username into a variable
TEST_PAYLOAD_AUTHOR=$(echo "$TEST_PAYLOAD" | jq -r --arg AUTHOR "${AUTHOR}" 'select(.author==$AUTHOR) | .author')
# Capture the number of issues created by the same issue creator
TEST_PAYLOAD_AUTHOR_COUNT=$(echo "$TEST_PAYLOAD" | jq -r --arg AUTHOR "${AUTHOR}" 'select(.author==$AUTHOR) | .count')
#echo -e "#######################################################\nIssue Author: ${TEST_PAYLOAD_AUTHOR}\nCount: ${TEST_PAYLOAD_AUTHOR_COUNT}\nIssues:\n${TEST_PAYLOAD_AUTHOR_ISSUE_URL}\n#######################################################\n"
# Output the results
echo -e "<a href="https://github.com/${TEST_PAYLOAD_AUTHOR}">${TEST_PAYLOAD_AUTHOR}</a> - ${TEST_PAYLOAD_AUTHOR_COUNT}"
# Sort the data and pipe into a text file
done | sort -n -k 4,4 -r >> output.txt
}
contributor_json () {
# Process data about who appled the linked label (contributor)
CONTRIBUTORS=$(cat issues.json| jq -r '.contributor' | sort | uniq -c | awk -F " " '{print "{\"contributor\":""\""$2"\""",\"count\":" $1"}"}' | jq -r .contributor)
echo -e "Contributors that linked issues" >> output.txt
# Iterate through all issue contributors found in the temp json like file
for CONTRIBUTOR in ${CONTRIBUTORS}; do
# Capture the issue contributor data into a variable
TEST_PAYLOAD=$(cat issues.json| jq -r '.contributor' | sort | uniq -c | awk -F " " '{print "{\"contributor\":""\""$2"\""",\"count\":" $1"}"}' | jq -r .)
# Capture the issue contributor username into a variable
TEST_PAYLOAD_CONTRIBUTOR=$(echo "$TEST_PAYLOAD" | jq -r --arg CONTRIBUTOR "${CONTRIBUTOR}" 'select(.contributor==$CONTRIBUTOR) | .contributor')
# Capture the number of issues linked by the same issue contributor
TEST_PAYLOAD_CONTRIBUTOR_COUNT=$(echo "$TEST_PAYLOAD" | jq -r --arg CONTRIBUTOR "${CONTRIBUTOR}" 'select(.contributor==$CONTRIBUTOR) | .count')
#TEST_PAYLOAD_CONTRIBUTOR_ISSUE_URL=$(cat issues.json | jq -r --arg CONTRIBUTOR "${CONTRIBUTOR}" 'select(.contributor==$CONTRIBUTOR) | .issue_url')
#TEST_PAYLOAD_CONTRIBUTOR_ISSUE_URL="https://github.com/chromiecraft/chromiecraft/issues?q=is%3Aissue+label%3A%22Linked+%5BAC%5D%22+involves%3A${CONTRIBUTOR}+created%3A2021-02-01T00%3A00..2021-02-28T23%3A59+is%3Aclosed"
#echo -e "#######################################################\nIssue Contributor: ${TEST_PAYLOAD_CONTRIBUTOR}\nCount: ${TEST_PAYLOAD_CONTRIBUTOR_COUNT}\nIssues:\n${TEST_PAYLOAD_CONTRIBUTOR_ISSUE_URL}\n#######################################################\n"
# Output the results
echo -e "<a href="https://github.com/${TEST_PAYLOAD_CONTRIBUTOR}">${TEST_PAYLOAD_CONTRIBUTOR}</a> - ${TEST_PAYLOAD_CONTRIBUTOR_COUNT}"
# Sort the data and pipe into a text file
done | sort -n -k 4,4 -r >> output.txt
}
# process the above functions in order
repo_issues
author_json
contributor_json
```