Skip to content

Fetch Latest Bandicoot Release #309

Fetch Latest Bandicoot Release

Fetch Latest Bandicoot Release #309

name: Fetch Latest Bandicoot Release
on:
workflow_dispatch: # Manual trigger
schedule:
- cron: '0 17 * * *' # Runs daily at 10 AM PDT (5 PM UTC)
jobs:
fetch-gitlab-release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up GitLab API access
id: setup
run: |
echo "GITLAB_API_URL=https://gitlab.com/api/v4" >> $GITHUB_ENV
echo "GITLAB_PROJECT_ID=bandicoot-lib/bandicoot-code" >> $GITHUB_ENV
- name: Get current version
id: current-version
run: |
if [ -f "inst/version.txt" ]; then
CURRENT_VERSION=$(cat inst/version.txt)
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "Current version: $CURRENT_VERSION"
else
echo "current_version=none" >> $GITHUB_OUTPUT
echo "No current version found"
fi
- name: Fetch latest release from GitLab
id: get-version
run: |
# bandicoot-lib/bandicoot-code is public; no auth needed.
RESPONSE=$(curl -s "$GITLAB_API_URL/projects/$(echo $GITLAB_PROJECT_ID | sed 's/\//%2F/g')/releases")
# Fail loudly if the response isn't the expected non-empty array
# (e.g. an API error object) instead of letting jq emit a cryptic error.
if ! echo "$RESPONSE" | jq -e 'type == "array" and length > 0' >/dev/null; then
echo "Unexpected GitLab API response (expected non-empty array of releases):"
echo "$RESPONSE"
exit 1
fi
# Cache the full response so later steps can read release name,
# date, and description without another API call.
printf '%s' "$RESPONSE" > /tmp/gitlab-release.json
# Extract the latest version and download URL
LATEST_VERSION=$(echo $RESPONSE | jq -r '.[0].tag_name')
DOWNLOAD_URL=$(echo $RESPONSE | jq -r '.[0].assets.sources[0].url')
# Remove 'v' prefix if present
LATEST_VERSION=${LATEST_VERSION#v}
# Set as output and environment variable
echo "version=$LATEST_VERSION" >> $GITHUB_OUTPUT
echo "download_url=$DOWNLOAD_URL" >> $GITHUB_OUTPUT
echo "LATEST_VERSION=$LATEST_VERSION" >> $GITHUB_ENV
# Log the fetched version
echo "Latest version: $LATEST_VERSION"
echo "Download URL: $DOWNLOAD_URL"
- name: Check if update is needed
id: check-update
run: |
if [ "${{ steps.current-version.outputs.current_version }}" != "${{ steps.get-version.outputs.version }}" ]; then
echo "update_needed=true" >> $GITHUB_OUTPUT
echo "Update needed: Current version ${{ steps.current-version.outputs.current_version }} differs from latest ${{ steps.get-version.outputs.version }}"
else
echo "update_needed=false" >> $GITHUB_OUTPUT
echo "No update needed: Current version matches latest version"
fi
- name: Download and extract release
if: steps.check-update.outputs.update_needed == 'true'
run: |
# Create temporary directory
mkdir -p temp_download
# Download the zip file
curl -L "${{ steps.get-version.outputs.download_url }}" -o temp_download/release.zip
# Extract the zip file
unzip temp_download/release.zip -d temp_download
# Find the bandicoot directory
BANDICOOT_DIR=$(find temp_download -name "bandicoot-code-*" -type d | head -1)
echo "Found Bandicoot directory: $BANDICOOT_DIR"
# Check if include directory exists
if [ -d "$BANDICOOT_DIR/include" ]; then
echo "Found include directory at $BANDICOOT_DIR/include"
# Wipe existing bandicoot_bits/ so we don't mix old and new content.
# Previously the mv below nested kernels/ inside a pre-existing ks/,
# producing ks/kernels/ paths that exceeded CRAN's 100-byte limit
# and left stale kernel sources behind.
rm -rf inst/include/bandicoot_bits inst/include/bandicoot
# Create destination directory if it doesn't exist
mkdir -p inst/include
# Copy the include directory contents
cp -r $BANDICOOT_DIR/include/* inst/include/
# Rename kernels/ to ks/ to avoid >100 char path warnings
# See PR #17: Installing kernels in 'ks/' avoids nag on > 100 chars
if [ -d "inst/include/bandicoot_bits/kernels" ]; then
mv inst/include/bandicoot_bits/kernels inst/include/bandicoot_bits/ks
echo "Renamed bandicoot_bits/kernels to bandicoot_bits/ks"
fi
# List copied files for verification
echo "Copied files to inst/include:"
ls -la inst/include/
else
echo "Error: include directory not found in $BANDICOOT_DIR"
echo "Directory contents:"
ls -la $BANDICOOT_DIR
exit 1
fi
# Clean up
rm -rf temp_download
# Update version file
mkdir -p inst
echo "${{ steps.get-version.outputs.version }}" > inst/version.txt
- name: Update DESCRIPTION and NEWS.md
if: steps.check-update.outputs.update_needed == 'true'
run: |
LATEST_VERSION="${{ steps.get-version.outputs.version }}"
PKG_VERSION="${LATEST_VERSION}.1"
# Bump package version in DESCRIPTION
sed -i "s/^Version: .*/Version: ${PKG_VERSION}/" DESCRIPTION
# Generate a polished NEWS entry (capitalization, backticks, HTML
# cleanup, 80-col line wrap) and prepend it to NEWS.md. The entry
# is still a DRAFT - the PR reviewer polishes wording that
# requires human judgment (merging related bullets, word choice).
python3 .github/scripts/format-news-entry.py /tmp/gitlab-release.json \
> /tmp/news-entry.md
{
cat /tmp/news-entry.md
[ -f NEWS.md ] && cat NEWS.md
} > NEWS.md.new
mv NEWS.md.new NEWS.md
echo "=== DESCRIPTION Version line ==="
grep '^Version:' DESCRIPTION
echo "=== NEWS.md head ==="
head -20 NEWS.md
- name: Create Pull Request
if: steps.check-update.outputs.update_needed == 'true'
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Update to Bandicoot release ${{ steps.get-version.outputs.version }}"
title: "Update Bandicoot to version ${{ steps.get-version.outputs.version }}"
body: |
This PR updates the Bandicoot library from version ${{ steps.current-version.outputs.current_version }} to ${{ steps.get-version.outputs.version }}.
Changes:
- Updated `inst/include/` files from the latest release
- Updated version in `inst/version.txt`
- Bumped `DESCRIPTION` to `${{ steps.get-version.outputs.version }}.1`
- Prepended a draft release-notes entry to `NEWS.md`. Mechanical
formatting (capitalization, backticks around `.method()`/
`function()` calls, HTML → Markdown, 80-col wrap, prose → bullet)
is applied by `.github/scripts/format-news-entry.py`. Please
still review for editorial polish (merging related bullets,
word choice) before merging.
This PR was automatically generated by the Fetch Latest Bandicoot Release workflow.
branch: update-bandicoot-${{ steps.get-version.outputs.version }}
base: main
labels: |
dependency
automated pr