Skip to content

Commit 79b0abb

Browse files
committed
update to carpentry workflows from incubator example
1 parent 34aa3bf commit 79b0abb

11 files changed

Lines changed: 821 additions & 311 deletions
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
name: "03 Maintain: Apply Package Cache"
2+
description: "Build and publish the lesson dependency image after a pull request has been merged or via manual trigger"
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
name:
7+
description: 'Who triggered this build?'
8+
required: true
9+
default: 'Maintainer (via GitHub)'
10+
force-dependency-image-rebuild:
11+
description: 'Rebuild the dependency image layer even if one already exists?'
12+
required: false
13+
default: false
14+
type: boolean
15+
prune-keep-count:
16+
description: 'How many existing dependency image layers to keep?'
17+
required: false
18+
default: 1
19+
type: number
20+
pull_request:
21+
types:
22+
- closed
23+
branches:
24+
- main
25+
26+
# queue cache runs
27+
concurrency:
28+
group: docker-apply-cache
29+
cancel-in-progress: false
30+
31+
jobs:
32+
preflight:
33+
name: "Preflight: PR or Manual Trigger?"
34+
runs-on: ubuntu-latest
35+
outputs:
36+
do-apply: ${{ steps.check.outputs.merged_or_manual }}
37+
steps:
38+
- name: "Should we run cache application?"
39+
id: check
40+
run: |
41+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ||
42+
("${{ github.ref }}" == "refs/heads/main" && "${{ github.event.action }}" == "closed" && "${{ github.event.pull_request.merged }}" == "true") ]]; then
43+
echo "merged_or_manual=true" >> $GITHUB_OUTPUT
44+
else
45+
echo "This was not a manual trigger and no PR was merged. No action taken."
46+
echo "merged_or_manual=false" >> $GITHUB_OUTPUT
47+
fi
48+
shell: bash
49+
50+
check-renv:
51+
name: "Check If We Need {renv}"
52+
runs-on: ubuntu-latest
53+
needs: preflight
54+
if: needs.preflight.outputs.do-apply == 'true'
55+
outputs:
56+
renv-needed: ${{ steps.check-for-renv.outputs.renv-needed }}
57+
renv-cache-hashsum: ${{ steps.check-for-renv.outputs.renv-cache-hashsum }}
58+
steps:
59+
- name: "Check for renv"
60+
id: check-for-renv
61+
uses: carpentries/actions/renv-checks@v1
62+
with:
63+
WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG || 'latest' }}
64+
skip-cache-check: true
65+
66+
no-renv-cache-used:
67+
name: "No renv package dependency image needed"
68+
runs-on: ubuntu-latest
69+
needs: check-renv
70+
if: needs.check-renv.outputs.renv-needed != 'true'
71+
steps:
72+
- name: "No dependency image needed"
73+
run: echo "No renv dependency image needed for this lesson"
74+
75+
update-renv-cache:
76+
name: "Publish renv package dependency image"
77+
runs-on: ubuntu-latest
78+
needs: check-renv
79+
if: needs.check-renv.outputs.renv-needed == 'true'
80+
permissions:
81+
contents: read
82+
packages: write
83+
steps:
84+
- uses: actions/checkout@v6
85+
86+
- name: "Get Container Version Used"
87+
id: wb-vers
88+
uses: carpentries/actions/container-version@v1
89+
with:
90+
WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG }}
91+
renv-needed: ${{ needs.check-renv.outputs.renv-needed }}
92+
token: ${{ secrets.GITHUB_TOKEN }}
93+
94+
- name: Log in to GHCR
95+
uses: docker/login-action@v4
96+
with:
97+
registry: ghcr.io
98+
username: ${{ github.actor }}
99+
password: ${{ secrets.GITHUB_TOKEN }}
100+
101+
- name: Set dependency image tags
102+
id: image
103+
env:
104+
IMAGE_OWNER: ${{ github.repository_owner }}
105+
IMAGE_NAME: ${{ github.event.repository.name }}
106+
WB_VERSION: ${{ steps.wb-vers.outputs.container-version }}
107+
RENV_HASH: ${{ needs.check-renv.outputs.renv-cache-hashsum }}
108+
run: |
109+
set -euo pipefail
110+
exact_image="ghcr.io/${IMAGE_OWNER}/${IMAGE_NAME}-deps:${WB_VERSION}_renv-${RENV_HASH}"
111+
latest_image="ghcr.io/${IMAGE_OWNER}/${IMAGE_NAME}-deps:latest"
112+
113+
# lowercaseify
114+
echo "exact_image=${exact_image,,}" >> "$GITHUB_OUTPUT"
115+
echo "latest_image=${latest_image,,}" >> "$GITHUB_OUTPUT"
116+
shell: bash
117+
118+
- name: Check for existing dependency image tag
119+
id: image-exists
120+
env:
121+
EXACT_IMAGE: ${{ steps.image.outputs.exact_image }}
122+
run: |
123+
set -euo pipefail
124+
if docker manifest inspect "${EXACT_IMAGE}" >/dev/null 2>&1; then
125+
echo "exists=true" >> "$GITHUB_OUTPUT"
126+
echo "## ⚠️ Dependency image already exists" >> $GITHUB_STEP_SUMMARY
127+
echo "Dependency image already exists for this renv hash: ${EXACT_IMAGE}" >> $GITHUB_STEP_SUMMARY
128+
echo "Dependency image already exists for this renv hash: ${EXACT_IMAGE}"
129+
else
130+
echo "exists=false" >> "$GITHUB_OUTPUT"
131+
echo "No existing dependency image found for this renv hash: ${EXACT_IMAGE}"
132+
fi
133+
shell: bash
134+
135+
- name: Build and push dependency image layer
136+
id: build-push-deps-layer
137+
if: |
138+
steps.image-exists.outputs.exists != 'true' ||
139+
(
140+
github.event_name == 'workflow_dispatch' &&
141+
github.event.inputs.force-dependency-image-rebuild == 'true'
142+
)
143+
uses: carpentries/actions/build-dependency-image@v1
144+
with:
145+
workbench-tag: ${{ vars.WORKBENCH_TAG || 'latest' }}
146+
github-token: ${{ secrets.GITHUB_TOKEN }}
147+
github-repository: ${{ github.repository }}
148+
github-sha: ${{ github.sha }}
149+
exact-image: ${{ steps.image.outputs.exact_image }}
150+
latest-image: ${{ steps.image.outputs.latest_image }}
151+
build-context: ${{ github.workspace }}
152+
153+
prune-dependency-images:
154+
name: "Prune Dependency Images"
155+
runs-on: ubuntu-latest
156+
needs: check-renv
157+
steps:
158+
- name: Prune any old dependency image layers
159+
uses: carpentries/actions/prune-dependency-images@v1
160+
if: needs.check-renv.outputs.renv-needed == 'true'
161+
with:
162+
github-token: ${{ secrets.GITHUB_TOKEN }}
163+
owner: ${{ github.repository_owner }}
164+
owner-type: ${{ github.event.repository.owner.type }}
165+
repository: ${{ github.event.repository.name }}
166+
package-name: ${{ github.event.repository.name }}-deps
167+
keep-count: ${{ github.event.inputs.prune-keep-count }}
168+
continue-on-error: true
169+
170+
record-cache-result:
171+
name: "Record Caching Status"
172+
runs-on: ubuntu-latest
173+
needs: [check-renv, update-renv-cache]
174+
if: always()
175+
env:
176+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
177+
steps:
178+
- name: "Record cache result"
179+
run: |
180+
echo "${{ needs.check-renv.outputs.renv-needed != 'true' || needs.update-renv-cache.result == 'success' }}" > ${{ github.workspace }}/apply-cache-result
181+
shell: bash
182+
183+
- name: "Upload cache result"
184+
uses: actions/upload-artifact@v7
185+
with:
186+
name: apply-cache-result
187+
path: ${{ github.workspace }}/apply-cache-result
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
name: "01 Maintain: Build and Deploy Site"
2+
description: "Build and deploy the lesson site using the carpentries/workbench-docker container"
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
- 'l10n_main'
8+
paths-ignore:
9+
- '.github/workflows/**.yaml'
10+
- '.github/workbench-docker-version.txt'
11+
schedule:
12+
- cron: '0 0 * * 2'
13+
workflow_run:
14+
workflows: ["03 Maintain: Apply Package Cache"]
15+
types:
16+
- completed
17+
workflow_dispatch:
18+
inputs:
19+
name:
20+
description: 'Who triggered this build?'
21+
required: true
22+
default: 'Maintainer (via GitHub)'
23+
CACHE_VERSION:
24+
description: 'Optional renv cache version override'
25+
required: false
26+
default: ''
27+
reset:
28+
description: 'Reset cached markdown files'
29+
required: true
30+
default: false
31+
type: boolean
32+
force-skip-manage-deps:
33+
description: 'Skip build-time dependency management'
34+
required: true
35+
default: false
36+
type: boolean
37+
38+
# only one build/deploy at a time
39+
concurrency:
40+
group: docker-build-deploy
41+
cancel-in-progress: true
42+
43+
jobs:
44+
preflight:
45+
name: "Preflight: Schedule, Push, or PR?"
46+
runs-on: ubuntu-latest
47+
outputs:
48+
do-build: ${{ steps.build-check.outputs.do-build }}
49+
renv-needed: ${{ steps.build-check.outputs.renv-needed }}
50+
renv-cache-hashsum: ${{ steps.build-check.outputs.renv-cache-hashsum }}
51+
dependency-image-ref: ${{ steps.build-check.outputs.dependency-image-ref }}
52+
workbench-container-file-exists: ${{ steps.wb-vers.outputs.workbench-container-file-exists }}
53+
wb-vers: ${{ steps.wb-vers.outputs.container-version }}
54+
last-wb-vers: ${{ steps.wb-vers.outputs.last-container-version }}
55+
workbench-update: ${{ steps.wb-vers.outputs.workbench-update }}
56+
env:
57+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
steps:
59+
- name: "Should we run build and deploy?"
60+
id: build-check
61+
uses: carpentries/actions/build-preflight@v1
62+
63+
- name: "Checkout Lesson"
64+
if: steps.build-check.outputs.do-build == 'true'
65+
uses: actions/checkout@v6
66+
67+
- name: "Get container version info"
68+
id: wb-vers
69+
if: steps.build-check.outputs.do-build == 'true'
70+
uses: carpentries/actions/container-version@v1
71+
with:
72+
WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG }}
73+
renv-needed: ${{ steps.build-check.outputs.renv-needed }}
74+
token: ${{ secrets.GITHUB_TOKEN }}
75+
76+
full-build:
77+
name: "Build Full Site"
78+
runs-on: ubuntu-latest
79+
needs: preflight
80+
if: |
81+
needs.preflight.outputs.do-build == 'true' &&
82+
needs.preflight.outputs.workbench-update != 'true'
83+
env:
84+
RENV_EXISTS: ${{ needs.preflight.outputs.renv-needed }}
85+
RENV_HASH: ${{ needs.preflight.outputs.renv-cache-hashsum }}
86+
permissions:
87+
checks: write
88+
contents: write
89+
pages: write
90+
container:
91+
image: ${{ needs.preflight.outputs.dependency-image-ref }}
92+
env:
93+
WORKBENCH_PROFILE: "ci"
94+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
95+
RENV_PATHS_ROOT: /home/rstudio/lesson/renv
96+
RENV_PROFILE: "lesson-requirements"
97+
RENV_CONFIG_EXTERNAL_LIBRARIES: "/usr/local/lib/R/site-library"
98+
volumes:
99+
- ${{ github.workspace }}:/home/rstudio/lesson
100+
options: --cpus 1
101+
steps:
102+
- uses: actions/checkout@v6
103+
104+
- name: "Debugging Info"
105+
run: |
106+
cd /home/rstudio/lesson
107+
echo "Current Directory: $(pwd)"
108+
echo "RENV_HASH is $RENV_HASH"
109+
ls -lah /home/rstudio/.workbench
110+
ls -lah $(pwd)
111+
Rscript -e 'sessionInfo()'
112+
shell: bash
113+
114+
- name: "Mark Repository as Safe"
115+
run: |
116+
git config --global --add safe.directory $(pwd)
117+
shell: bash
118+
119+
- name: "Run Container and Build Site"
120+
id: build-and-deploy
121+
uses: carpentries/actions/build-and-deploy@v1
122+
with:
123+
reset: ${{ vars.BUILD_RESET || github.event.inputs.reset || 'false' }}
124+
skip-manage-deps: ${{ github.event.inputs.force-skip-manage-deps == 'true' || contains(needs.preflight.outputs.dependency-image-ref, '-deps:') }}
125+
lang-code: ${{ vars.LANG_CODE || '' }}
126+
127+
update-container-version:
128+
name: "Update container version used"
129+
runs-on: ubuntu-latest
130+
needs: [preflight]
131+
permissions:
132+
actions: write
133+
contents: write
134+
pull-requests: write
135+
id-token: write
136+
if: |
137+
needs.preflight.outputs.do-build == 'true' &&
138+
(
139+
needs.preflight.outputs.workbench-container-file-exists == 'false' ||
140+
needs.preflight.outputs.workbench-update == 'true'
141+
)
142+
steps:
143+
- name: "Record container version used"
144+
uses: carpentries/actions/record-container-version@v1
145+
with:
146+
CONTAINER_VER: ${{ needs.preflight.outputs.wb-vers }}
147+
AUTO_MERGE: ${{ vars.AUTO_MERGE_CONTAINER_VERSION_UPDATE || 'true' }}
148+
token: ${{ secrets.GITHUB_TOKEN }}
149+
role-to-assume: ${{ secrets.AWS_GH_OIDC_ARN }}
150+
aws-region: ${{ secrets.AWS_GH_OIDC_REGION }}

0 commit comments

Comments
 (0)