@@ -10,7 +10,8 @@ inputs:
1010 description : Whether or not to save (commit and push) results to Git and DVC remotes.
1111 default : " true"
1212 dvc_token :
13- description : DVC token for pushing results. If not provided, will be obtained
13+ description :
14+ DVC token for pushing results. If not provided, will be obtained
1415 via GitHub OIDC.
1516 required : false
1617 pull_dvc :
@@ -29,17 +30,201 @@ outputs: {}
2930runs :
3031 using : composite
3132 steps :
33+ - name : Detect setup requirements
34+ id : detect
35+ shell : bash
36+ run : |
37+ set -euo pipefail
38+
39+ has_kind() {
40+ local kind="$1"
41+ grep -Eiq "^[[:space:]]*kind:[[:space:]]*[\"']?${kind}([\"']?[[:space:]#]|$)" calkit.yaml
42+ }
43+
44+ if command -v calkit >/dev/null 2>&1; then
45+ calkit_missing=false
46+ else
47+ calkit_missing=true
48+ fi
49+ echo "calkit_missing=${calkit_missing}" >> "$GITHUB_OUTPUT"
50+
51+ if command -v uv >/dev/null 2>&1; then
52+ uv_missing=false
53+ else
54+ uv_missing=true
55+ fi
56+ echo "uv_missing=${uv_missing}" >> "$GITHUB_OUTPUT"
57+
58+ if command -v python >/dev/null 2>&1 || command -v python3 >/dev/null 2>&1; then
59+ python_missing=false
60+ else
61+ python_missing=true
62+ fi
63+
64+ if command -v conda >/dev/null 2>&1; then
65+ conda_missing=false
66+ else
67+ conda_missing=true
68+ fi
69+
70+ if command -v pixi >/dev/null 2>&1; then
71+ pixi_missing=false
72+ else
73+ pixi_missing=true
74+ fi
75+
76+ if command -v julia >/dev/null 2>&1; then
77+ julia_missing=false
78+ else
79+ julia_missing=true
80+ fi
81+
82+ if command -v Rscript >/dev/null 2>&1 || command -v R >/dev/null 2>&1; then
83+ r_missing=false
84+ else
85+ r_missing=true
86+ fi
87+
88+ if command -v matlab >/dev/null 2>&1; then
89+ matlab_missing=false
90+ else
91+ matlab_missing=true
92+ fi
93+
94+ if command -v docker >/dev/null 2>&1 && docker buildx version >/dev/null 2>&1; then
95+ docker_buildx_missing=false
96+ else
97+ docker_buildx_missing=true
98+ fi
99+
100+ needs_python=false
101+ needs_conda=false
102+ needs_pixi=false
103+ needs_julia=false
104+ needs_r=false
105+ needs_matlab=false
106+ needs_docker=false
107+ unsupported_kinds=""
108+
109+ if [ -f calkit.yaml ]; then
110+ if has_kind "uv-venv" || has_kind "venv"; then
111+ if [ "$python_missing" = true ]; then
112+ needs_python=true
113+ fi
114+ fi
115+ if has_kind "conda"; then
116+ if [ "$conda_missing" = true ]; then
117+ needs_conda=true
118+ fi
119+ if [ "$python_missing" = true ]; then
120+ needs_python=true
121+ fi
122+ fi
123+ if has_kind "pixi"; then
124+ if [ "$pixi_missing" = true ]; then
125+ needs_pixi=true
126+ fi
127+ fi
128+ if has_kind "julia"; then
129+ if [ "$julia_missing" = true ]; then
130+ needs_julia=true
131+ fi
132+ fi
133+ if has_kind "renv"; then
134+ if [ "$r_missing" = true ]; then
135+ needs_r=true
136+ fi
137+ fi
138+ if has_kind "matlab"; then
139+ if [ "$matlab_missing" = true ]; then
140+ needs_matlab=true
141+ fi
142+ fi
143+ if has_kind "docker"; then
144+ if [ "$docker_buildx_missing" = true ]; then
145+ needs_docker=true
146+ fi
147+ fi
148+
149+ # These kinds do not have a direct setup action in this composite action.
150+ if has_kind "ssh"; then unsupported_kinds="${unsupported_kinds}ssh,"; fi
151+ if has_kind "slurm"; then unsupported_kinds="${unsupported_kinds}slurm,"; fi
152+ unsupported_kinds="${unsupported_kinds%,}"
153+ fi
154+
155+ echo "needs_python=${needs_python}" >> "$GITHUB_OUTPUT"
156+ echo "needs_conda=${needs_conda}" >> "$GITHUB_OUTPUT"
157+ echo "needs_pixi=${needs_pixi}" >> "$GITHUB_OUTPUT"
158+ echo "needs_julia=${needs_julia}" >> "$GITHUB_OUTPUT"
159+ echo "needs_r=${needs_r}" >> "$GITHUB_OUTPUT"
160+ echo "needs_matlab=${needs_matlab}" >> "$GITHUB_OUTPUT"
161+ echo "needs_docker=${needs_docker}" >> "$GITHUB_OUTPUT"
162+ echo "unsupported_kinds=${unsupported_kinds}" >> "$GITHUB_OUTPUT"
163+
164+ - name : Setup uv
165+ if : ${{ steps.detect.outputs.calkit_missing == 'true' && steps.detect.outputs.uv_missing == 'true' }}
166+ uses : astral-sh/setup-uv@v5
167+
168+ - name : Install Calkit
169+ if : ${{ steps.detect.outputs.calkit_missing == 'true' }}
170+ shell : bash
171+ run : |
172+ uv tool install calkit-python
173+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
174+
175+ - name : Setup Python
176+ if : ${{ steps.detect.outputs.needs_python == 'true' }}
177+ uses : actions/setup-python@v5
178+ with :
179+ python-version : " 3.x"
180+
181+ - name : Setup Miniconda
182+ if : ${{ steps.detect.outputs.needs_conda == 'true' }}
183+ uses : conda-incubator/setup-miniconda@v3
184+ with :
185+ auto-activate-base : true
186+
187+ - name : Setup Pixi
188+ if : ${{ steps.detect.outputs.needs_pixi == 'true' }}
189+ uses : prefix-dev/setup-pixi@v0
190+
191+ - name : Setup Julia
192+ if : ${{ steps.detect.outputs.needs_julia == 'true' }}
193+ uses : julia-actions/setup-julia@v2
194+ with :
195+ version : " 1"
196+
197+ - name : Setup R
198+ if : ${{ steps.detect.outputs.needs_r == 'true' }}
199+ uses : r-lib/actions/setup-r@v2
200+
201+ - name : Setup MATLAB
202+ if : ${{ steps.detect.outputs.needs_matlab == 'true' }}
203+ uses : matlab-actions/setup-matlab@v2
204+
205+ - name : Setup Docker Buildx
206+ if : ${{ steps.detect.outputs.needs_docker == 'true' }}
207+ uses : docker/setup-buildx-action@v3
208+
209+ - name : Report unsupported environment kinds
210+ if : ${{ steps.detect.outputs.unsupported_kinds != '' }}
211+ shell : bash
212+ run : |
213+ echo "::notice::Detected environment kinds without explicit setup action: ${{ steps.detect.outputs.unsupported_kinds }}"
214+
32215 - name : Restore DVC cache for current branch
33216 if : ${{ inputs.cache_dvc == 'true' }}
34217 id : cache-dvc-restore
35218 uses : actions/cache/restore@v5
36219 with :
37220 path : .dvc/cache
38- key : ${{ runner.os }}-dvc-cache-${{ github.head_ref || github.ref_name }}-${{
221+ key :
222+ ${{ runner.os }}-dvc-cache-${{ github.head_ref || github.ref_name }}-${{
39223 github.sha }}
40224 restore-keys : |
41225 ${{ runner.os }}-dvc-cache-${{ github.head_ref || github.ref_name }}-
42226 ${{ runner.os }}-dvc-cache-${{ github.event.repository.default_branch }}-
227+
43228 - name : Get GitHub OIDC token
44229 if : ${{ !inputs.dvc_token && (inputs.save == 'true' || inputs.pull_dvc ==
45230 ' true' ) }}
53238 fi
54239 echo "::add-mask::$OIDC_TOKEN"
55240 echo "oidc-token=$OIDC_TOKEN" >> $GITHUB_OUTPUT
241+
56242 - name : Exchange OIDC token for Calkit token
57243 if : ${{ !inputs.dvc_token && (inputs.save == 'true' || inputs.pull_dvc ==
58244 ' true' ) }}
68254 fi
69255 echo "::add-mask::$CALKIT_TOKEN"
70256 echo "calkit-token=$CALKIT_TOKEN" >> $GITHUB_OUTPUT
257+
71258 - run : calkit config remote-auth
72259 if : ${{ inputs.save == 'true' || inputs.pull_dvc == 'true' }}
73260 shell : bash
@@ -86,11 +273,13 @@ runs:
86273 env :
87274 CALKIT_TOKEN : ${{ inputs.dvc_token || steps.get-calkit-token.outputs.calkit-token }}
88275 CALKIT_DVC_TOKEN : ${{ inputs.dvc_token || steps.get-calkit-token.outputs.calkit-token }}
276+
89277 - name : Save DVC cache
90278 if : ${{ inputs.cache_dvc == 'true' }}
91279 id : cache-dvc-save
92280 uses : actions/cache/save@v5
93281 with :
94282 path : .dvc/cache
95- key : ${{ runner.os }}-dvc-cache-${{ github.head_ref || github.ref_name }}-${{
283+ key :
284+ ${{ runner.os }}-dvc-cache-${{ github.head_ref || github.ref_name }}-${{
96285 github.sha }}
0 commit comments