Skip to content

Commit 7736041

Browse files
authored
Merge pull request #48 from nmfs-opensci/eeholmes-patch-2
Add action to create draft GitHub release from Dockerfile
2 parents 4f9ea95 + 2e7fd86 commit 7736041

3 files changed

Lines changed: 274 additions & 146 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Create draft release
2+
description: Create a draft GitHub Release using VERSION from Dockerfile (YYYY.MM.DD). Fails if VERSION is missing or malformed.
3+
4+
inputs:
5+
tag_prefix:
6+
description: Optional prefix for the tag (e.g. v). Default is empty.
7+
required: false
8+
default: ""
9+
dockerfile_path:
10+
description: Path to Dockerfile to parse version from
11+
required: false
12+
default: Dockerfile
13+
target:
14+
description: Git ref/sha to tag (default: current commit SHA)
15+
required: false
16+
default: ""
17+
generate_notes:
18+
description: Whether to auto-generate release notes (true/false)
19+
required: false
20+
default: "true"
21+
22+
runs:
23+
using: composite
24+
steps:
25+
- name: Extract and validate VERSION
26+
id: ver
27+
shell: bash
28+
run: |
29+
set -euo pipefail
30+
df="${{ inputs.dockerfile_path }}"
31+
32+
if [ ! -f "$df" ]; then
33+
echo "::error::Dockerfile not found at: $df"
34+
exit 1
35+
fi
36+
37+
if grep -q "LABEL org.opencontainers.image.version=" "$df"; then
38+
version=$(grep "LABEL org.opencontainers.image.version=" "$df" | head -1 | cut -d '=' -f2- | tr -d ' "')
39+
elif grep -q "LABEL VERSION=" "$df"; then
40+
version=$(grep "LABEL VERSION=" "$df" | head -1 | cut -d '=' -f2- | tr -d ' "')
41+
else
42+
echo "::error::No VERSION label found in $df"
43+
exit 1
44+
fi
45+
46+
if ! echo "$version" | grep -Eq '^[0-9]{4}\.[0-9]{2}\.[0-9]{2}$'; then
47+
echo "::error::Invalid VERSION format: '$version' (expected YYYY.MM.DD)"
48+
exit 1
49+
fi
50+
51+
tag="${{ inputs.tag_prefix }}${version}"
52+
echo "Resolved tag: $tag"
53+
echo "TAG=$tag" >> "$GITHUB_ENV"
54+
55+
- name: Create draft release (fails if tag already exists)
56+
shell: bash
57+
env:
58+
GH_TOKEN: ${{ github.token }}
59+
run: |
60+
set -euo pipefail
61+
62+
tag="${TAG}"
63+
title="Release ${tag}"
64+
target="${{ inputs.target }}"
65+
66+
if [ -z "$target" ]; then
67+
target="${GITHUB_SHA}"
68+
fi
69+
70+
if gh release view "$tag" >/dev/null 2>&1; then
71+
echo "::error::Release for tag '$tag' already exists."
72+
exit 1
73+
fi
74+
75+
args=(release create "$tag" --draft --title "$title" --target "$target")
76+
77+
if [ "${{ inputs.generate_notes }}" = "true" ]; then
78+
args+=(--generate-notes)
79+
fi
80+
81+
gh "${args[@]}"
82+
echo "✓ Draft release created for tag $tag"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Validate packages in container
2+
description: Extract pinned Python/R package lists from a Docker image and run repo validation scripts, producing reproducibility/build.log.
3+
4+
inputs:
5+
image:
6+
description: Full image reference including tag (e.g. ghcr.io/org/repo/image:sha)
7+
required: true
8+
repo_root_mount:
9+
description: Host repo mount path inside container (default: /repo)
10+
required: false
11+
default: /repo
12+
python_version:
13+
description: Python version for running validation scripts on the runner
14+
required: false
15+
default: "3.11"
16+
17+
runs:
18+
using: composite
19+
steps:
20+
- name: Ensure reproducibility directory exists
21+
shell: bash
22+
run: |
23+
set -euo pipefail
24+
mkdir -p reproducibility
25+
26+
- name: Extract base environment.yaml from container
27+
shell: bash
28+
run: |
29+
set -euo pipefail
30+
docker run --rm --entrypoint cat \
31+
"${{ inputs.image }}" \
32+
/srv/repo/environment.yml > base-environment.yaml
33+
echo "Base environment.yaml extracted to base-environment.yaml"
34+
head -20 base-environment.yaml || true
35+
36+
- name: Extract Python packages with pinned versions
37+
shell: bash
38+
run: |
39+
set -euo pipefail
40+
docker run --rm "${{ inputs.image }}" \
41+
bash -lc 'conda list -n notebook --export' > reproducibility/packages-python-pinned.yaml
42+
echo "Python packages extracted to reproducibility/packages-python-pinned.yaml"
43+
head -20 reproducibility/packages-python-pinned.yaml || true
44+
45+
- name: Set up Python for validation
46+
uses: actions/setup-python@v5
47+
with:
48+
python-version: ${{ inputs.python_version }}
49+
50+
- name: Install Python dependencies
51+
shell: bash
52+
run: |
53+
set -euo pipefail
54+
python -m pip install --upgrade pip
55+
pip install pyyaml
56+
57+
- name: Filter and validate Python packages
58+
shell: bash
59+
run: |
60+
set -euo pipefail
61+
python .github/scripts/filter_and_validate_packages.py
62+
echo "Validation complete. Check reproducibility/build.log for results."
63+
test -f reproducibility/build.log && cat reproducibility/build.log || true
64+
65+
- name: Extract R packages with pinned versions
66+
shell: bash
67+
run: |
68+
set -euo pipefail
69+
docker run --rm \
70+
-v "$PWD:${{ inputs.repo_root_mount }}" \
71+
"${{ inputs.image }}" \
72+
Rscript "${{ inputs.repo_root_mount }}/.github/scripts/extract_pins_r.R" /usr/local/lib/R/site-library \
73+
> reproducibility/packages-r-pinned.R
74+
echo "R packages extracted to reproducibility/packages-r-pinned.R"
75+
head -30 reproducibility/packages-r-pinned.R || true
76+
77+
- name: Validate R packages
78+
shell: bash
79+
run: |
80+
set -euo pipefail
81+
docker run --rm "${{ inputs.image }}" cat /rocker_scripts/install_geospatial.sh > /tmp/install_geospatial.sh
82+
docker run --rm "${{ inputs.image }}" cat /rocker_scripts/install_tidyverse.sh > /tmp/install_tidyverse.sh
83+
84+
python .github/scripts/validate_r_packages.py
85+
86+
echo "R package validation complete. Check reproducibility/build.log for results."
87+
test -f reproducibility/build.log && cat reproducibility/build.log || true
88+
89+
- name: Compute validation status (writes to step summary)
90+
shell: bash
91+
run: |
92+
set -euo pipefail
93+
success_count=$(grep -c "STATUS: SUCCESS" reproducibility/build.log 2>/dev/null || true)
94+
if [ "$success_count" -eq 2 ]; then
95+
echo "✅ validation_status=success" | tee -a "$GITHUB_STEP_SUMMARY"
96+
else
97+
echo "⚠️ validation_status=failed" | tee -a "$GITHUB_STEP_SUMMARY"
98+
fi

0 commit comments

Comments
 (0)