1- name : " Export Tutorials "
1+ name : " Export Tutorial on Comment "
22
33on :
4- workflow_dispatch :
5- push :
6- branches :
7- - " dev"
8- - " master"
9- paths :
10- - ' tutorials/**/*.ipynb'
4+ issue_comment :
5+ types : [created]
116
127jobs :
13- # run on push
14- export_tutorials_on_push :
15- if : ${{ github.event_name == 'push' }}
16- permissions : write-all
8+ export_on_comment :
9+ if : github.event.issue.pull_request && startsWith(github.event.comment.body, '/tutorial-exporter')
1710 runs-on : ubuntu-latest
11+ permissions :
12+ pull-requests : write
13+ contents : read
1814 env :
1915 TUTORIAL_TIMEOUT : 1200s
16+
2017 steps :
21- - uses : actions/checkout@v4
22-
23- - name : Set up Python
24- uses : actions/setup-python@v5
25- with :
26- python-version : 3.9
27-
28- - name : Install dependencies
29- run : |
30- # Dependencies for tutorials
31- python3 -m pip install --upgrade pip .[tutorial] black[jupyter]
32- - name : Setup FFmpeg
33- uses : FedericoCarboni/setup-ffmpeg@v2
34-
35- - id : files
36- uses : jitterbit/get-changed-files@v1
37- with :
38- token : ${{ secrets.GITHUB_TOKEN }}
39- format : space-delimited
40-
41- - name : Configure git
42- run : |
43- git config user.name "github-actions[bot]"
44- git config user.email 41898282+github-actions[bot]@users.noreply.github.com
45-
46- - name : Run formatter
47- run : black tutorials/
48-
49- - name : Export tutorials to .py and .html
50- run : |
51- set -x
52- for file in ${{ steps.files.outputs.all }}; do
53- if [[ $file == *.ipynb ]]; then
54- filename=$(basename $file)
55- pyfilename=$(echo ${filename%?????})py
56- timeout --signal=SIGKILL $TUTORIAL_TIMEOUT python -Xfrozen_modules=off -m jupyter nbconvert $file --to python --output $pyfilename --output-dir=$(dirname $file)
57- htmlfilename=$(echo ${filename%?????} | sed -e 's/-//g')html
58- htmldir="docs/source"/$(echo ${file%??????????????} | sed -e 's/-//g')
59- timeout --signal=SIGKILL $TUTORIAL_TIMEOUT python -Xfrozen_modules=off -m jupyter nbconvert --execute $file --to html --output $htmlfilename --output-dir=$htmldir
18+ # Detect PR branch from comment
19+ - name : Get PR branch from comment
20+ uses : xt0rted/pull-request-comment-branch@v1
21+ id : comment-branch
22+
23+ - name : Set latest commit status as pending
24+ uses : myrotvorets/set-commit-status-action@master
25+ with :
26+ sha : ${{ steps.comment-branch.outputs.head_sha }}
27+ token : ${{ secrets.GITHUB_TOKEN }}
28+ status : pending
29+
30+ # Checkout the PR branch
31+ - name : Checkout PR branch ${{ steps.comment-branch.outputs.head_ref }}
32+ uses : actions/checkout@v3
33+ with :
34+ ref : ${{ steps.comment-branch.outputs.head_ref }}
35+
36+ # Setup Python
37+ - name : Set up Python
38+ uses : actions/setup-python@v5
39+ with :
40+ python-version : 3.10
41+
42+ # Install dependencies
43+ - name : Install dependencies
44+ run : python3 -m pip install --upgrade pip .[tutorial] black[jupyter]
45+
46+ # Setup FFmpeg (if needed)
47+ - name : Setup FFmpeg
48+ uses : FedericoCarboni/setup-ffmpeg@v2
49+
50+ # Format notebooks
51+ - name : Run formatter
52+ run : black tutorials/
53+
54+ # Export the tutorial to .py
55+ - name : Export tutorial to .py
56+ run : |
57+ set -euo pipefail
58+ COMMENT_BODY="${{ github.event.comment.body }}"
59+ TUTORIAL_NUM=$(echo "$COMMENT_BODY" | awk '{print $2}')
60+ FILE="tutorials/tutorial${TUTORIAL_NUM}.ipynb"
61+
62+ if [[ -f "$FILE" ]]; then
63+ echo "Exporting $FILE"
64+ PYFILENAME="${FILE%.ipynb}.py"
65+ timeout --signal=SIGKILL $TUTORIAL_TIMEOUT \
66+ python -Xfrozen_modules=off -m jupyter nbconvert \
67+ "$FILE" --to python --output "$PYFILENAME" --output-dir=$(dirname "$FILE")
68+ else
69+ echo "Tutorial $TUTORIAL_NUM not found: $FILE"
70+ exit 1
6071 fi
61- done
62- set +x
63-
64- -
uses :
benjlevesque/[email protected] 65- id : short-sha
66-
67- - name : Remove unwanted files
68- run : |
69- rm -rf build/ tutorials/tutorial4/data/
70-
71- - name : Create Pull Request
72- uses :
peter-evans/[email protected] 73- with :
74- labels : maintenance
75- title : Export tutorial changed in ${{ steps.short-sha.outputs.sha }}
76- branch : export-tutorial-${{ steps.short-sha.outputs.sha }}
77- base : ${{ github.head_ref }}
78- commit-message : export tutorials changed in ${{ steps.short-sha.outputs.sha }}
79- delete-branch : true
80-
81- # run on workflow_dispatch
82- export_tutorials_workflow_dispatch :
83- if : ${{ github.event_name == 'workflow_dispatch' }}
84- permissions : write-all
85- runs-on : ubuntu-latest
86- env :
87- TUTORIAL_TIMEOUT : 1200s
88- steps :
89- - uses : actions/checkout@v4
90-
91- - name : Set up Python
92- uses : actions/setup-python@v5
93- with :
94- python-version : 3.9
95-
96- - name : Install dependencies
97- run : |
98- python3 -m pip install --upgrade pip .[tutorial] black[jupyter]
99-
100- - name : Setup FFmpeg
101- uses : FedericoCarboni/setup-ffmpeg@v2
102-
103- - name : Configure git
104- run : |
105- git config user.name "github-actions[bot]"
106- git config user.email 41898282+github-actions[bot]@users.noreply.github.com
107-
108- - name : Run formatter
109- run : black tutorials/
110-
111- - name : Export all tutorials to .py and .html
112- run : |
113- set -x
114- # Find all .ipynb files in the tutorials directory
115- for file in $(find tutorials -type f -name "*.ipynb"); do
116- filename=$(basename $file)
117- pyfilename="${filename%.ipynb}.py"
118- timeout --signal=SIGKILL $TUTORIAL_TIMEOUT python -Xfrozen_modules=off -m jupyter nbconvert $file --to python --output $pyfilename --output-dir=$(dirname $file)
119- htmlfilename="${filename%.ipynb}.html"
120- htmldir="docs/source"/$(dirname $file)
121- timeout --signal=SIGKILL $TUTORIAL_TIMEOUT python -Xfrozen_modules=off -m jupyter nbconvert --execute $file --to html --output $htmlfilename --output-dir=$htmldir
122- done
123- set +x
124-
125- -
uses :
benjlevesque/[email protected] 126- id : short-sha
127-
128- - name : Remove unwanted files
129- run : |
130- rm -rf build/ tutorials/tutorial4/data/
131-
132- - name : Create Pull Request
133- uses :
peter-evans/[email protected] 134- with :
135- labels : maintenance
136- title : Export tutorial changed in ${{ steps.short-sha.outputs.sha }}
137- branch : export-tutorial-${{ steps.short-sha.outputs.sha }}
138- base : ${{ github.head_ref }}
139- commit-message : export tutorials changed in ${{ steps.short-sha.outputs.sha }}
140- delete-branch : true
72+
73+ # Create a PR
74+ -
uses :
benjlevesque/[email protected] 75+ id : short-sha
76+
77+ - name : Remove unwanted files
78+ run : |
79+ rm -rf build/
80+ rm -rf tutorials/tutorial12/SegTrackv2/
81+
82+ - name : Create Pull Request
83+ uses :
peter-evans/[email protected] 84+ with :
85+ labels : maintenance
86+ title : Export tutorial to .py in ${{ steps.short-sha.outputs.sha }}
87+ branch : export-tutorial-${{ steps.short-sha.outputs.sha }}
88+ commit-message : export tutorial to .py in ${{ steps.short-sha.outputs.sha }}
89+ delete-branch : true
90+
91+ - name : Add workflow result as comment on PR
92+ uses : actions/github-script@v6
93+ if : always()
94+ with :
95+ script : |
96+ const name = '${{ github.workflow }}';
97+ const url = '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}';
98+ const success = '${{ job.status }}' === 'success';
99+ const body = `${name}: ${success ? 'succeeded ✅' : 'failed ❌'}\n${url}`;
100+
101+ await github.rest.issues.createComment({
102+ issue_number: context.issue.number,
103+ owner: context.repo.owner,
104+ repo: context.repo.repo,
105+ body: body
106+ })
107+
108+ - name : Set latest commit status as ${{ job.status }}
109+ uses : myrotvorets/set-commit-status-action@master
110+ if : always()
111+ with :
112+ sha : ${{ steps.comment-branch.outputs.head_sha }}
113+ token : ${{ secrets.GITHUB_TOKEN }}
114+ status : ${{ job.status }}
0 commit comments