Skip to content

Bump version to 1.10.1 #63

Bump version to 1.10.1

Bump version to 1.10.1 #63

Workflow file for this run

name: Build and Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
# Tests must pass before any release artifacts are built
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Check formatting
run: npm run format:check
- name: Run linter
run: npm run lint
- name: Security audit
run: npm audit --audit-level=high
- name: Run tests
run: npm run test:run
- name: Verify build
run: npm run build
# Validate release type - full releases require existing prerelease
validate:
needs: test
runs-on: ubuntu-latest
outputs:
is_prerelease: ${{ steps.check.outputs.is_prerelease }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Determine release type
id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
VERSION="${TAG#v}"
# Extract base version (strip prerelease suffix)
BASE_VERSION=$(echo "$VERSION" | sed 's/-.*//')
# Check if this is a prerelease tag (contains -alpha, -beta, -rc, etc.)
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-.+ ]]; then
echo "is_prerelease=true" >> $GITHUB_OUTPUT
echo "This is a PRE-RELEASE: $TAG"
else
echo "is_prerelease=false" >> $GITHUB_OUTPUT
echo "This is a FULL RELEASE: $TAG"
# Check if a prerelease exists for this version
PRERELEASES=$(gh release list --limit 100 | grep -E "${BASE_VERSION}-(alpha|beta|rc)" || true)
if [ -z "$PRERELEASES" ]; then
echo "::error::No pre-release found for version $BASE_VERSION. Create a pre-release first (e.g., v${BASE_VERSION}-beta.1)"
exit 1
else
echo "Found pre-releases for this version:"
echo "$PRERELEASES"
fi
fi
# Clean up invalid releases - delete tag if validation failed
cleanup-invalid:
needs: [test, validate]
if: failure()
runs-on: ubuntu-latest
steps:
- name: Delete invalid tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
echo "Cleaning up invalid release: $TAG"
# Delete the release if it exists
gh release delete "$TAG" --repo "$GITHUB_REPOSITORY" --yes 2>/dev/null || echo "No release to delete"
# Delete the tag
git push --delete origin "$TAG" 2>/dev/null || echo "No remote tag to delete"
echo ""
echo "Invalid release $TAG has been deleted."
# Verify package.json version matches tag
verify-version:
needs: validate
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Verify version match
run: |
TAG="${GITHUB_REF#refs/tags/}"
TAG_VERSION="${TAG#v}"
# Extract base version (strip prerelease suffix)
TAG_BASE=$(echo "$TAG_VERSION" | sed 's/-.*//')
PKG_VERSION=$(node -p "require('./package.json').version")
echo "Tag version: $TAG_VERSION (base: $TAG_BASE)"
echo "Package.json version: $PKG_VERSION"
if [ "$TAG_BASE" != "$PKG_VERSION" ]; then
echo "::error::Version mismatch! Tag ($TAG_BASE) does not match package.json ($PKG_VERSION)"
exit 1
fi
echo "Version verified: $PKG_VERSION"
# Create the GitHub release first (so builds can upload to it)
create-release:
needs: [validate, verify-version]
runs-on: ubuntu-latest
steps:
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
IS_PRERELEASE="${{ needs.validate.outputs.is_prerelease }}"
NOTES="## Installation
**macOS:** Open Terminal and run: \`xattr -cr /Applications/Graph\\ Core.app\` then open the app.
**Windows:** Run the installer. Click \"More info\" then \"Run anyway\" if you see a SmartScreen warning.
**Linux:** Make the AppImage executable: \`chmod +x Graph-Core-*.AppImage\`"
if [ "$IS_PRERELEASE" = "true" ]; then
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --draft --prerelease --generate-notes --notes "$NOTES"
echo "Created draft prerelease: $TAG"
else
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --draft --generate-notes --notes "$NOTES"
echo "Created draft release: $TAG"
fi
# Build release artifacts and upload to the release
build:
needs: [validate, verify-version, create-release]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build app
run: npm run build
- name: Build Electron (macOS)
if: matrix.os == 'macos-latest'
run: npx electron-builder --mac --publish never
env:
CSC_IDENTITY_AUTO_DISCOVERY: false
- name: Build Electron (Windows)
if: matrix.os == 'windows-latest'
run: npx electron-builder --win --publish never
- name: Build Electron (Linux)
if: matrix.os == 'ubuntu-latest'
run: npx electron-builder --linux --publish never
- name: Upload artifacts to release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
echo "Uploading artifacts to release $TAG"
# Upload all release files except blockmap and debug yml files
for file in release/*; do
if [ -f "$file" ]; then
filename=$(basename "$file")
# Skip blockmap and builder-debug.yml, but include latest*.yml for auto-updates
if [[ "$filename" != *.blockmap && "$filename" != "builder-debug.yml" ]]; then
echo "Uploading: $filename"
gh release upload "$TAG" "$file" --repo "$GITHUB_REPOSITORY" --clobber
fi
fi
done
# Publish the release (remove draft status)
publish-release:
needs: [validate, build]
runs-on: ubuntu-latest
steps:
- name: Publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
IS_PRERELEASE="${{ needs.validate.outputs.is_prerelease }}"
echo "Publishing release: $TAG"
if [ "$IS_PRERELEASE" = "true" ]; then
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false --prerelease
echo "Published prerelease: $TAG"
else
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false --prerelease=false
echo "Published release: $TAG"
fi
# Upload release assets to R2 (full releases only)
upload-r2:
needs: [validate, publish-release]
if: needs.validate.outputs.is_prerelease == 'false'
runs-on: ubuntu-latest
steps:
- name: Download release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p assets
gh release download "${{ github.ref_name }}" --repo "${{ github.repository }}" --dir assets
- name: Upload to R2
env:
RCLONE_CONFIG_R2_TYPE: s3
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
RCLONE_CONFIG_R2_ENDPOINT: https://78836246513c4e18ead5fd9349aea200.r2.cloudflarestorage.com
run: |
curl -s https://rclone.org/install.sh | sudo bash
# Generate index.html
cat > assets/index.html << 'EOF'
<!DOCTYPE html>
<html><head><title>Graph Core Downloads</title>
<style>body{font-family:system-ui;max-width:800px;margin:2rem auto;padding:1rem}
a{display:block;padding:0.5rem 0}</style></head>
<body><h1>Graph Core Downloads</h1>
EOF
for f in assets/*; do
[ -f "$f" ] && echo "<a href=\"$(basename "$f")\">$(basename "$f")</a>" >> assets/index.html
done
echo "</body></html>" >> assets/index.html
echo "Files to upload:"
ls -la assets/
# First upload new files (copy doesn't delete anything)
rclone copy assets/ r2:binaries/graph-core/ -v
# Verify upload succeeded by checking a file exists in R2
if rclone ls r2:binaries/graph-core/ | head -1 | grep -q .; then
echo "Upload verified, cleaning up old versions..."
# Now safe to sync (deletes old files since new ones exist)
rclone sync assets/ r2:binaries/graph-core/ -v
else
echo "::error::Upload verification failed - keeping old files"
exit 1
fi
# Trigger website to update download links
trigger-website:
needs: upload-r2
runs-on: ubuntu-latest
steps:
- name: Trigger sorenwacker.net update
env:
PAT_TOKEN: ${{ secrets.WEBSITE_DISPATCH_TOKEN }}
run: |
curl -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $PAT_TOKEN" \
https://api.github.com/repos/sorenwacker/sorenwacker.net/dispatches \
-d '{"event_type":"graph-core-release","client_payload":{"version":"${{ github.ref_name }}"}}'