Skip to content

Commit 6a7c138

Browse files
committed
Add GitHub Actions to build PDFs and comment on pull requests
Use GitHub's recommended two-part approach [1][2] to separate building the PDFs (which runs in the PR branch's context and has only a read-only GH token) from commenting on the PR (which runs on the master branch and has write access to the repository). Add a brief README (to be expanded as this beds in), and mention in the old README that the old implementation will soon be removed: the CircleCI web hook and its access token have been removed from the hts-specs repo. [1] https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ [2] https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow
1 parent 59a0d0c commit 6a7c138

6 files changed

Lines changed: 167 additions & 0 deletions

File tree

.circleci/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[The CircleCI web hook has been deactivated in favour of GitHub Actions. This legacy infrastructure will be removed once that has bedded in.]
2+
13
We use [circle-ci](https://circleci.com/gh/samtools/hts-specs) to build the pdfs and highlight the differences for each pull-request. This is done at several steps.
24

35
1. Circle-ci runs `make` and copies the pdfs and log files to an "artifacts" directory for that build.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: texlive
2+
description: Run commands in a TeXLive docker image
3+
4+
inputs:
5+
run:
6+
description: Commands to be executed
7+
required: true
8+
9+
runs:
10+
using: docker
11+
image: docker://texlive/texlive:latest
12+
entrypoint: /bin/sh
13+
args:
14+
- -c
15+
- ${{ inputs.run }}

.github/workflows/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
This repository uses GitHub Actions to build draft PDFs and comment on pull requests.
2+
3+
Several workflows are defined, using GitHub's recommended [two-part approach] to separate building the PDFs (which runs in the PR branch's context and has only a read-only GH token) from commenting on the PR (which runs on the **master** branch and has write access to the repository).
4+
5+
* _pr-pdf.yaml_ runs on `*.tex`-modifying pull requests, and runs LaTeX using the _texlive_ action defined in this repository.
6+
* _pr-comment.yaml_ runs on completion of _pr-pdf.yaml_, and comments on the PR.
7+
* _pr-pdfs-close.yaml_ runs when a PR is merged or closed, and removes the Git reference to the draft PDF commits so they will eventually be garbage-collected.
8+
9+
10+
[two-part approach]: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/

.github/workflows/pr-comment.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Add PR comment
2+
3+
on:
4+
workflow_run:
5+
workflows: ["Handle PDF pull request"]
6+
types: [completed]
7+
8+
jobs:
9+
comment:
10+
runs-on: ubuntu-latest
11+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
12+
env:
13+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
run_id: ${{ github.event.workflow_run.id }}
15+
16+
steps:
17+
- uses: actions/checkout@v3
18+
19+
- name: Download artifacts
20+
run: |
21+
gh run download --dir artifact --name pdf $run_id
22+
cat artifact/environ.txt >> $GITHUB_ENV
23+
24+
- name: Check out preview ref
25+
run: |
26+
git fetch --depth=1 origin refs/preview/$pr_number:pr || git fetch --depth=1 origin $base_sha:pr
27+
git switch pr
28+
rm -rf new diff
29+
mv artifact/new artifact/diff .
30+
31+
- name: Compose comment
32+
shell: python
33+
env:
34+
view_url: https://cdn.jsdelivr.net/gh/${{ github.repository }}@<SHA>
35+
run: |
36+
import os
37+
38+
head_sha = os.environ['head_sha']
39+
view_url = os.environ['view_url']
40+
41+
files = []
42+
links = []
43+
for pdf in sorted(os.listdir("new")):
44+
new_pdf = os.path.join("new", pdf)
45+
diff_pdf = os.path.join("diff", pdf)
46+
47+
text = f"[{os.path.splitext(pdf)[0]}]({view_url}/{new_pdf})"
48+
files.append(new_pdf)
49+
if os.path.exists(diff_pdf):
50+
text += f" ([diff]({view_url}/{diff_pdf}))"
51+
files.append(diff_pdf)
52+
links.append(text)
53+
54+
with open(os.environ['GITHUB_ENV'], 'a') as outf:
55+
files_text = " ".join(files)
56+
print(f"pdf_files={files_text}", file=outf)
57+
58+
links_text = ", ".join(links)
59+
print(f"comment=Changed PDFs as of {head_sha}: {links_text}.", file=outf)
60+
61+
- name: Update preview ref
62+
env:
63+
GIT_AUTHOR_NAME: hts-specs bot
64+
GIT_COMMITTER_NAME: hts-specs bot
65+
EMAIL: hts-specs-bot@broadinstitute.org
66+
run: |
67+
git add -f $pdf_files
68+
git commit --allow-empty -m "PDFs for PR #$pr_number as of $head_sha"
69+
git push origin pr:refs/preview/$pr_number
70+
71+
- name: Add PR comment
72+
shell: bash
73+
run: |
74+
gh pr comment --body "${comment//<SHA>/$(git rev-parse pr)}" $pr_number
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Tidy up PDF pull request
2+
3+
on:
4+
pull_request_target:
5+
paths: '*.tex'
6+
types: [closed]
7+
8+
jobs:
9+
clean:
10+
runs-on: ubuntu-latest
11+
env:
12+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13+
pr_number: ${{ github.event.number }}
14+
15+
steps:
16+
- name: Remove preview ref
17+
continue-on-error: true
18+
run: |
19+
gh api --method DELETE repos/$GITHUB_REPOSITORY/git/refs/preview/$pr_number

.github/workflows/pr-pdfs.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Handle PDF pull request
2+
3+
on:
4+
pull_request:
5+
paths: '*.tex'
6+
7+
jobs:
8+
LaTeX:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
with:
13+
fetch-depth: 0
14+
15+
- name: Identify changed LaTeX documents
16+
env:
17+
pr_number: ${{ github.event.number }}
18+
base_sha: ${{ github.event.pull_request.base.sha }}
19+
head_sha: ${{ github.event.pull_request.head.sha }}
20+
run: |
21+
mergebase_sha=$(git merge-base $base_sha $head_sha)
22+
echo "mergebase_sha=$mergebase_sha" >> $GITHUB_ENV
23+
changed=$(git diff-tree --name-only --merge-base $base_sha $head_sha -- '*.tex' | tr '\n' ' ')
24+
echo "changed=$changed" >> $GITHUB_ENV
25+
echo "pdfs=$(ls -1 $changed | sed 's,^,new/,;s,tex$,pdf,' | tr '\n' ' ')" >> $GITHUB_ENV
26+
echo "diffs=$(ls -1 $changed | sed 's,^,diff/,;s,tex$,pdf,' | tr '\n' ' ')" >> $GITHUB_ENV
27+
28+
echo "pr_number=$pr_number" > environ.txt
29+
echo "base_sha=$base_sha" >> environ.txt
30+
echo "head_sha=$head_sha" >> environ.txt
31+
echo "mergebase_sha=$mergebase_sha" >> environ.txt
32+
33+
- name: Run LaTeX
34+
uses: ./.github/actions/texlive
35+
if: ${{ env.changed }}
36+
with:
37+
run: make ${{ env.pdfs }} && make -k OLD=$mergebase_sha NEW=HEAD ${{ env.diffs }}
38+
39+
- uses: actions/upload-artifact@v3
40+
with:
41+
name: pdf
42+
retention-days: 1
43+
if-no-files-found: ignore
44+
path: |
45+
environ.txt
46+
new/*.pdf
47+
diff/*.pdf

0 commit comments

Comments
 (0)