Files
aaddrick--claude-desktop-de…/.github/workflows/check-claude-version.yml
T
wehub-resource-sync 3e076d4dd9
Deploy Worker / deploy (push) Failing after 1s
Shellcheck / Check shell scripts (push) Failing after 1s
CI / Build Packages (amd64 - appimage) (push) Has been skipped
CI / Build Packages (amd64 - deb) (push) Has been skipped
CI / Build Packages (amd64 - rpm) (push) Has been skipped
CI / Build Packages (arm64 - appimage) (push) Has been skipped
CI / Build Packages (arm64 - deb) (push) Has been skipped
CI / Test Flags Parsing (push) Failing after 1s
BATS Tests / BATS unit tests (push) Failing after 1s
CI / Build Packages (arm64 - rpm) (push) Has been skipped
CI / Test Build Artifacts (amd64) (push) Has been skipped
CI / Test Build Artifacts (arm64) (push) Has been skipped
CI / Update APT Repository (push) Has been cancelled
CI / Mirror Official .deb to Release (push) Has been cancelled
CI / Update DNF Repository (push) Has been cancelled
CI / Update AUR Package (push) Has been cancelled
CI / Create Release (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:29:21 +08:00

214 lines
8.4 KiB
YAML

name: Check Claude Desktop Version
on:
schedule:
- cron: "0 1 * * *"
workflow_dispatch:
permissions:
contents: write
concurrency:
group: main-branch-auto-update
cancel-in-progress: false
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
token: ${{ secrets.GH_PAT }}
- name: Resolve newest official versions
id: resolve
run: |
source scripts/_common.sh
source scripts/setup/official-deb.sh
# amd64 is authoritative — a failure here fails the job.
if ! resolve_official_deb amd64; then
echo "::error::Failed to resolve amd64 official package"
exit 1
fi
{
echo "amd64_version=$resolved_official_version"
echo "amd64_filename=$resolved_official_filename"
echo "amd64_sha256=$resolved_official_sha256"
} >> "$GITHUB_OUTPUT"
# arm64 may lag the pool; a failure just leaves arm64_version
# empty, which the cross-arch gate treats as "not yet published".
if resolve_official_deb arm64; then
{
echo "arm64_version=$resolved_official_version"
echo "arm64_filename=$resolved_official_filename"
echo "arm64_sha256=$resolved_official_sha256"
} >> "$GITHUB_OUTPUT"
else
echo "::warning::Failed to resolve arm64 official package"
fi
- name: Check if update needed
id: check_update
run: |
AMD64_VERSION="${{ steps.resolve.outputs.amd64_version }}"
ARM64_VERSION="${{ steps.resolve.outputs.arm64_version }}"
CURRENT_PIN=$(grep -oP "^OFFICIAL_DEB_VERSION='\K[^']+" \
scripts/setup/official-deb.sh)
STORED_CLAUDE_VERSION="${{ vars.CLAUDE_DESKTOP_VERSION }}"
REPO_VERSION="${{ vars.REPO_VERSION }}"
echo "Resolved amd64 version: $AMD64_VERSION"
echo "Resolved arm64 version: $ARM64_VERSION"
echo "Current pin (OFFICIAL_DEB_VERSION): $CURRENT_PIN"
echo "Stored CLAUDE_DESKTOP_VERSION: $STORED_CLAUDE_VERSION"
echo "Repository version: $REPO_VERSION"
# Cross-arch agreement gate: the official pool occasionally
# publishes one arch ahead of the other. Only bump when both
# arches expose the same version, so a half-published release
# never pins mismatched binaries.
if [[ "$AMD64_VERSION" != "$ARM64_VERSION" ]]; then
echo "pool lag — arches disagree" \
"(amd64='$AMD64_VERSION' arm64='$ARM64_VERSION');" \
"skipping until both publish"
echo "update_needed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
VER="$AMD64_VERSION"
UPDATE_NEEDED=false
if [[ "$VER" != "$CURRENT_PIN" ]]; then
echo "Version differs from pin ($CURRENT_PIN -> $VER)"
UPDATE_NEEDED=true
fi
if [[ "$VER" != "$STORED_CLAUDE_VERSION" ]]; then
echo "Version differs from CLAUDE_DESKTOP_VERSION"
UPDATE_NEEDED=true
fi
if [[ "$UPDATE_NEEDED" == "true" ]]; then
NEW_TAG="v${REPO_VERSION}+claude${VER}"
{
echo "update_needed=true"
echo "claude_version=$VER"
echo "new_tag=$NEW_TAG"
} >> "$GITHUB_OUTPUT"
echo "Update needed! New tag will be: $NEW_TAG"
else
echo "No updates needed"
echo "update_needed=false" >> "$GITHUB_OUTPUT"
fi
- name: Update official-deb.sh pins
if: steps.check_update.outputs.update_needed == 'true'
run: |
VER="${{ steps.check_update.outputs.claude_version }}"
AMD64_FILENAME="${{ steps.resolve.outputs.amd64_filename }}"
AMD64_SHA256="${{ steps.resolve.outputs.amd64_sha256 }}"
ARM64_FILENAME="${{ steps.resolve.outputs.arm64_filename }}"
ARM64_SHA256="${{ steps.resolve.outputs.arm64_sha256 }}"
f="scripts/setup/official-deb.sh"
# The resolver's Filename: field is already pool-relative, so it
# drops straight into the OFFICIAL_DEB_POOL_* pins. Each sed
# anchors on ^NAME= so the five pin lines rewrite unambiguously.
# '|' delimiter clears the '/' in the pool paths.
sed -i "s|^OFFICIAL_DEB_VERSION=.*|OFFICIAL_DEB_VERSION='$VER'|" "$f"
sed -i "s|^OFFICIAL_DEB_POOL_AMD64=.*|OFFICIAL_DEB_POOL_AMD64='$AMD64_FILENAME'|" "$f"
sed -i "s|^OFFICIAL_DEB_SHA256_AMD64=.*|OFFICIAL_DEB_SHA256_AMD64='$AMD64_SHA256'|" "$f"
sed -i "s|^OFFICIAL_DEB_POOL_ARM64=.*|OFFICIAL_DEB_POOL_ARM64='$ARM64_FILENAME'|" "$f"
sed -i "s|^OFFICIAL_DEB_SHA256_ARM64=.*|OFFICIAL_DEB_SHA256_ARM64='$ARM64_SHA256'|" "$f"
echo "Updated pins in $f:"
grep -E "^OFFICIAL_DEB_(VERSION|POOL|SHA256)" "$f"
- name: Update Nix SRI hashes
if: steps.check_update.outputs.update_needed == 'true'
run: |
NIX_FILE="nix/claude-desktop.nix"
# The Nix derivation is a `throw` stub until @typedrat lands the
# official-deb rework. Skip cleanly until it exposes a real
# `version = "..."` line to anchor on.
if ! grep -q 'version = ' "$NIX_FILE"; then
echo "nix derivation is still a stub; skipping SRI update"
exit 0
fi
VER="${{ steps.check_update.outputs.claude_version }}"
AMD64_SHA256="${{ steps.resolve.outputs.amd64_sha256 }}"
ARM64_SHA256="${{ steps.resolve.outputs.arm64_sha256 }}"
# The APT Packages index SHA-256 is authoritative — no download.
# Convert the hex digest to the SRI (base64) form Nix expects.
amd64_sri="sha256-$(echo "$AMD64_SHA256" | xxd -r -p | base64 -w0)"
arm64_sri="sha256-$(echo "$ARM64_SHA256" | xxd -r -p | base64 -w0)"
sed -i "s|version = \"[^\"]*\"|version = \"$VER\"|" "$NIX_FILE"
# Expected per-arch block shape once the derivation lands:
# x86_64-linux = { url = "..."; hash = "sha256-..."; };
# aarch64-linux = { url = "..."; hash = "sha256-..."; };
# Each arch block holds exactly one `hash = "..."` before its
# closing `};`, so the range sed rewrites only that arch's hash.
sed -i "/x86_64-linux/,/};/{s|hash = \"[^\"]*\"|hash = \"$amd64_sri\"|}" "$NIX_FILE"
sed -i "/aarch64-linux/,/};/{s|hash = \"[^\"]*\"|hash = \"$arm64_sri\"|}" "$NIX_FILE"
echo "Updated $NIX_FILE (version + per-arch SRI hashes)"
- name: Commit and push changes
if: steps.check_update.outputs.update_needed == 'true'
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
run: |
VER="${{ steps.check_update.outputs.claude_version }}"
NEW_TAG="${{ steps.check_update.outputs.new_tag }}"
# Check if we have a PAT
if [ -z "$GH_TOKEN" ]; then
echo "Error: GH_PAT secret is not configured"
exit 1
fi
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Check if there are changes to commit
if git diff --quiet scripts/setup/official-deb.sh nix/claude-desktop.nix; then
echo "No changes to scripts/setup/official-deb.sh or nix/claude-desktop.nix"
else
git add scripts/setup/official-deb.sh nix/claude-desktop.nix
git commit -m "$(cat <<COMMIT_MSG
Update Claude Desktop to version $VER
Bumped the official .deb pins (version, pool paths, SHA-256) and
the Nix SRI hashes to the newest release in Anthropic's official
APT pool.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
COMMIT_MSG
)"
git push
echo "Changes committed and pushed"
fi
# Update the version variable
gh variable set CLAUDE_DESKTOP_VERSION --body "$VER"
echo "Creating and pushing new tag: $NEW_TAG"
# Create annotated tag
git tag -a "$NEW_TAG" -m "Update to Claude Desktop $VER"
# Push the tag
git push origin "$NEW_TAG"
echo "Successfully created tag $NEW_TAG"