Skip to content

Commit

Permalink
Automate chapter progress monitoring (#990)
Browse files Browse the repository at this point in the history
* Add alt="" for the decorative images. #439

* Consistent titles and subtitles. #439

* generate

* Add mising bold font (#632)

* Add Workflow to track chapter progress

* Change config constants all caps

* Keep unfinished tasks empty in the grid

* Parse known links and add draft link

* Add columns for Links and Team

* Skip issues with zero or unexpected number of tasks

* Update workflow trigger logic

Co-authored-by: Barry Pollard <[email protected]>

* Add logging for debugging corner cases

* Use correct terminology as issue number not id

* Update control flow to skip invalid tasks

* Use issue update as trigger with label filter

* Prevent manual trigger from being skipped

* Parametrize number of tasks and simply control flow

Co-authored-by: Barry Pollard <[email protected]>

* Parse TOTAL_TRACKED_TASKS environment variable as integer

* Update icon for draft link

* Remove debug message that is no longer relevant

* Add more dubugging messages to show the progress

* Exclude links as the base SQL dir

Co-authored-by: Catalin Rosu <[email protected]>
Co-authored-by: Rick Viscomi <[email protected]>
Co-authored-by: Barry <[email protected]>
Co-authored-by: Barry Pollard <[email protected]>
  • Loading branch information
5 people committed Jul 10, 2020
1 parent 5375166 commit abf4318
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions .github/workflows/progress-tracker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Progress Tracker

env:
# Update these environment variables every year
FILTER_LABEL: '2020 chapter'
TRACKER_ISSUE_NUMBER: 989
TOTAL_TRACKED_TASKS: 10
SQL_BASE_DIR: 'https://github.com/HTTPArchive/almanac.httparchive.org/tree/main/sql/2020/'

on:
workflow_dispatch:
issues:
types:
- edited

jobs:
track-progress:
name: Track Progress
if: github.repository == 'HTTPArchive/almanac.httparchive.org'
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v2
if: github.event_name == 'workflow_dispatch' || contains(github.event.issue.labels.*.name, env.FILTER_LABEL)
with:
script: |
const filterLabel = process.env.FILTER_LABEL
const trackerIssueNumber = process.env.TRACKER_ISSUE_NUMBER
const totalTrackedTasks = parseInt(process.env.TOTAL_TRACKED_TASKS, 10)
const sqlBaseDir = process.env.SQL_BASE_DIR
const parseTasks = text => {
const tasks = []
text.split('\n').forEach(line => {
if (/^(\s{2,})?([*+-]|\d+\.)\s+\[ \]\s+\S+/.test(line)) {
tasks.push('')
}
if (/^(\s{2,})?([*+-]|\d+\.)\s+\[[xX]\]\s+\S+/.test(line)) {
tasks.push('☑')
}
})
return tasks
}
const parseLinks = text => {
const links = {}
text.split('\n').forEach(line => {
const linkMap = {
draft: /^\[~draft-doc\]:\s*(?<link>\S+)/,
sql: /^\[~sql-dir\]:\s*(?<link>\S+)/,
results: /^\[~results-sheet\]:\s*(?<link>\S+)/
}
for (const [k, v] of Object.entries(linkMap)) {
const m = line.match(v)
if (m) {
links[k] = m.groups.link
}
}
})
return links
}
const parseTeam = text => {
const team = {}
text.split('\n').forEach(line => {
if (/\|\s*\[Sheet\]\[~results-sheet\]\s*\|/.test(line)) {
const [, authors, reviewers, analysts] = line.split('|')
team.authors = [...authors.matchAll(/@(?<username>\w+)/g)].map(u => u.groups.username)
team.reviewers = [...reviewers.matchAll(/@(?<username>\w+)/g)].map(u => u.groups.username)
team.analysts = [...analysts.matchAll(/@(?<username>\w+)/g)].map(u => u.groups.username)
}
})
return team
}
const formatLinks = links => {
const icons = {
draft: '📄',
sql: '🔍',
results: '📊'
}
return Object.entries(links).filter(l => !['', '#', sqlBaseDir].includes(l[1])).map(l => `[${icons[l[0]] || l[0]}](${l[1]})`).join(' ')
}
const formatTeam = team => {
return Object.entries(team).map(m => m[1].length).join('/')
}
const taskIssues = await github.paginate(github.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
direction: 'asc',
labels: filterLabel
})
let report = ''
let chapters = 0
for (const issue of taskIssues) {
const tasksStatus = parseTasks(issue.body)
const tasksCount = tasksStatus.length
if(tasksCount != totalTrackedTasks) {
core.info(`Skipping issue #${issue.number} with ${tasksCount} instead of ${totalTrackedTasks} tasks`)
continue
}
if(!report) {
report = `Chapters | Links | Team | ${tasksStatus.map((v, i) => i + 1).join(' | ')}\n`
report += `:--------|:------|:----:|:${tasksStatus.map(() => '-').join(':|:')}:\n`
}
const links = formatLinks(parseLinks(issue.body))
const team = formatTeam(parseTeam(issue.body))
core.info(`Adding issue #${issue.number} with ${tasksCount} tasks`)
chapters++
report += `[${issue.title.replace(/\s+\d+$/, '')}](${issue.html_url}) | ${links} | ${team} | ${tasksStatus.join(' | ')}\n`
}
const progressIssue = await github.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: trackerIssueNumber
})
github.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: trackerIssueNumber,
body: progressIssue.data.body.replace(/<!-- REPORT START -->[\s\S]*<!-- REPORT END -->/, `<!-- REPORT START -->\n${report}<!-- REPORT END -->`)
})
core.info(`Updated report in issue #${trackerIssueNumber} with ${chapters} chapters`)

0 comments on commit abf4318

Please sign in to comment.