diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1e9fb34 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,46 @@ +version: 2 +updates: + # Monitor GitHub Actions dependencies + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "02:00" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "github-actions" + commit-message: + prefix: "chore" + include: "scope" + reviewers: + - "proxay" + # Group all GitHub Actions updates into a single PR + groups: + github-actions: + patterns: + - "*" + + # Monitor Nix flake inputs + # Note: Dependabot doesn't natively support Nix flakes. + # Nix flake inputs (nixpkgs) are automatically updated via the + # 'update-flake-inputs.yml' workflow which runs weekly and creates PRs. + # + # Cursor version updates are handled by the 'update-cursor.yml' workflow + # which runs daily and automatically commits updates. + # + # Both workflows complement this Dependabot configuration to keep + # all dependencies up to date. + + # If you add Docker or other dependencies in the future, + # uncomment and configure as needed: + # - package-ecosystem: "docker" + # directory: "/" + # schedule: + # interval: "weekly" + # open-pull-requests-limit: 5 + # labels: + # - "dependencies" + # - "docker" + diff --git a/.github/workflows/update-cursor.yml b/.github/workflows/update-cursor.yml new file mode 100644 index 0000000..d791d62 --- /dev/null +++ b/.github/workflows/update-cursor.yml @@ -0,0 +1,87 @@ +name: Update Cursor + +on: + # Run daily at 2 AM UTC + schedule: + - cron: '0 2 * * *' + + # Allow manual trigger + workflow_dispatch: + +permissions: + contents: write + +jobs: + update-cursor: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: | + experimental-features = nix-command flakes + + - name: Run update script + id: update + continue-on-error: true + run: | + chmod +x update-cursor.sh + # Run the script in a nix shell with all required dependencies + nix shell nixpkgs#curl nixpkgs#htmlq nixpkgs#ripgrep --command ./update-cursor.sh + + - name: Check for changes + id: check_changes + run: | + if git diff --quiet flake.nix; then + echo "changed=false" >> $GITHUB_OUTPUT + echo "No changes detected" + else + echo "changed=true" >> $GITHUB_OUTPUT + echo "Changes detected in flake.nix" + fi + + - name: Get new version + id: version + if: steps.check_changes.outputs.changed == 'true' + run: | + VERSION=$(grep -o 'version = "[^"]*"' flake.nix | head -1 | sed 's/version = "//;s/"//') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "New version: $VERSION" + + - name: Commit and push changes + if: steps.check_changes.outputs.changed == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + # Only commit flake.nix as Cursor version changes don't affect flake.lock + # flake.lock is managed by the update-flake-inputs.yml workflow + git add flake.nix + git commit -m "chore: update Cursor to version ${{ steps.version.outputs.version }}" + git push + + - name: Create Release (optional) + if: steps.check_changes.outputs.changed == 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ steps.version.outputs.version }} + name: Cursor ${{ steps.version.outputs.version }} + body: | + Automated update to Cursor version ${{ steps.version.outputs.version }} + + ## Changes + - Updated Cursor AppImage URL + - Updated SHA256 hash + + Run `nix flake update` in your NixOS configuration to get the latest version. + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/update-flake-inputs.yml b/.github/workflows/update-flake-inputs.yml new file mode 100644 index 0000000..df3f2e9 --- /dev/null +++ b/.github/workflows/update-flake-inputs.yml @@ -0,0 +1,96 @@ +name: Update Nix Flake Inputs + +on: + # Run weekly on Monday at 3 AM UTC (after the daily Cursor update) + schedule: + - cron: '0 3 * * 1' + + # Allow manual trigger + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-flake-inputs: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + # Ensure we have the latest changes (important if cursor was just updated) + ref: main + + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: | + experimental-features = nix-command flakes + + - name: Update flake inputs + id: update + run: | + echo "Updating flake inputs..." + nix flake update + + # Check if there are any changes + if git diff --quiet flake.lock; then + echo "changed=false" >> $GITHUB_OUTPUT + echo "No updates available" + else + echo "changed=true" >> $GITHUB_OUTPUT + echo "Updates found in flake.lock" + fi + + - name: Test build after update + if: steps.update.outputs.changed == 'true' + run: | + echo "Testing build with updated inputs..." + nix build .#cursor --no-link + echo "Build test successful!" + + - name: Get nixpkgs version info + id: version_info + if: steps.update.outputs.changed == 'true' + run: | + # Extract nixpkgs revision from flake.lock + NIXPKGS_REV=$(jq -r '.nodes.nixpkgs.locked.rev' flake.lock | cut -c1-7) + echo "nixpkgs_rev=$NIXPKGS_REV" >> $GITHUB_OUTPUT + echo "New nixpkgs revision: $NIXPKGS_REV" + + - name: Create Pull Request + if: steps.update.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore(deps): update Nix flake inputs" + title: "chore(deps): Update Nix flake inputs" + body: | + ## 🔄 Automated Nix Flake Input Update + + This PR updates the Nix flake inputs, primarily nixpkgs. + + ### Changes + - Updated nixpkgs to revision `${{ steps.version_info.outputs.nixpkgs_rev }}` + - Updated `flake.lock` file + + ### Testing + - ✅ Build test passed with updated inputs + + ### Review + Please review the changes in `flake.lock` and ensure the build works as expected. + + --- + *This PR was automatically created by the Update Flake Inputs workflow.* + branch: automated/update-flake-inputs + delete-branch: true + labels: | + dependencies + nix + automated + draft: false + diff --git a/README.md b/README.md index ae3f0f4..2e0e2b8 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,27 @@ A clean, simple NixOS flake for packaging the [Cursor](https://cursor.sh/) AI-powered code editor. +## 🔄 Automated Dependency Management + +This repository features comprehensive automated dependency management: + +- ✅ **Daily Cursor updates** - Automatically checks and updates Cursor versions +- ✅ **Weekly Nix flake updates** - Updates nixpkgs and other inputs via PRs +- ✅ **Weekly GitHub Actions updates** - Dependabot keeps CI/CD dependencies current + +See [DEPENDENCY-MANAGEMENT.md](DEPENDENCY-MANAGEMENT.md) for detailed information. + ## 📦 What This Flake Provides This flake packages Cursor as a Nix package that can be easily integrated into any NixOS system or used standalone. **Packages:** + - `packages.x86_64-linux.cursor` - The Cursor editor with full desktop integration - `packages.x86_64-linux.default` - Same as cursor (default package) **Features:** + - ✅ **Complete Desktop Integration** - Includes icon extraction and desktop entry - ✅ **Icon Support** - Automatically extracts and installs Cursor icon from AppImage - ✅ **MIME Type Associations** - Supports opening various file types with Cursor @@ -81,23 +93,27 @@ nix run .#cursor When a new version of Cursor is released, use the included update script: ### Method 1: Automatic with URL + ```bash ./update-cursor.sh "https://downloads.cursor.com/production/[hash]/linux/x64/Cursor-1.6.0-x86_64.AppImage" ``` ### Method 2: Interactive + ```bash ./update-cursor.sh # Follow the prompts to enter version or URL ``` ### Method 3: Version number + ```bash ./update-cursor.sh "1.6.0" # Script will prompt for the full download URL ``` The script will automatically: + - ✅ Update the version in `flake.nix` - ✅ Update the download URL - ✅ Fetch and update the SHA256 hash @@ -107,17 +123,23 @@ The script will automatically: ## 📁 Repository Structure -``` +```text cursor-flake/ -├── flake.nix # Main flake configuration (package-only) -├── flake.lock # Flake lock file -├── update-cursor.sh # Update script for new versions -├── README.md # This file -├── LICENSE # MIT License -└── archive-old-system-configs/ # Archived old system configs - ├── configuration.nix # (archived - was for full system setup) - ├── home.nix # (archived - was for home-manager) - └── ... # (other archived files) +├── flake.nix # Main flake configuration (package-only) +├── flake.lock # Flake lock file +├── update-cursor.sh # Update script for new versions +├── README.md # This file +├── LICENSE # MIT License +├── DEPENDENCY-MANAGEMENT.md # Dependency management documentation +├── .github/ +│ ├── dependabot.yml # Dependabot configuration +│ └── workflows/ +│ ├── update-cursor.yml # Daily Cursor update workflow +│ └── update-flake-inputs.yml # Weekly flake update workflow +└── archive-old-system-configs/ # Archived old system configs + ├── configuration.nix # (archived - was for full system setup) + ├── home.nix # (archived - was for home-manager) + └── ... # (other archived files) ``` ## 🔧 Development @@ -142,9 +164,11 @@ If you prefer to update manually: 1. Get the new AppImage URL from [cursor.sh](https://cursor.sh) 2. Update version and URL in `flake.nix` 3. Get the new hash: + ```bash nix-prefetch-url "https://downloads.cursor.com/production/[hash]/linux/x64/Cursor-X.Y.Z-x86_64.AppImage" ``` + 4. Update the hash in `flake.nix` 5. Test: `nix build .#cursor` @@ -166,6 +190,7 @@ This flake uses `appimageTools.extract` and `appimageTools.wrapType2` to properl This flake was simplified from a previous version that included full NixOS system configurations. The old structure has been archived in `archive-old-system-configs/` for reference. **Benefits of the new structure:** + - ✅ **Focused**: Just packages Cursor, nothing else - ✅ **Reusable**: Easy to integrate into any NixOS system - ✅ **Maintainable**: No complex system configurations to maintain @@ -189,4 +214,4 @@ nix build .#cursor - [Cursor Official Website](https://cursor.sh/) - [NixOS Documentation](https://nixos.org/manual/nixos/stable/) -- [Nix Flakes Documentation](https://nixos.wiki/wiki/Flakes) \ No newline at end of file +- [Nix Flakes Documentation](https://nixos.wiki/wiki/Flakes) diff --git a/cursor-fix-solution.md b/cursor-fix-solution.md index 1637745..0ec23eb 100644 --- a/cursor-fix-solution.md +++ b/cursor-fix-solution.md @@ -4,7 +4,7 @@ The issue with Cursor when using the custom developed flake is related to native modules not being found when the AppImage runs. The error shows: -``` +```text Error: Cannot find module './build/Debug/keymapping' Require stack: - /home/user/.cache/appimage-run/d249132fa6429cbc46050495a19ed410e04db53655428955024ff631c095d11c/usr/share/cursor/resources/app/node_modules/native-keymap/index.js @@ -240,10 +240,13 @@ in 1. Open your `home.nix` file 2. Replace the existing `cursorAppImage` section with the updated version above 3. Rebuild your system with: + ```bash sudo nixos-rebuild switch --flake .#cursor-system ``` + 4. Test Cursor: + ```bash cursor --version ``` @@ -253,15 +256,17 @@ in If you still encounter issues: 1. Clear the AppImage cache: + ```bash rm -rf ~/.cache/appimage-run/* ``` 2. Try running Cursor with additional debugging: + ```bash cursor --enable-logging --v=1 ``` 3. Check if the issue persists in a fresh terminal session -These changes should resolve the native module loading issues you're experiencing with Cursor in your NixOS flake. \ No newline at end of file +These changes should resolve the native module loading issues you're experiencing with Cursor in your NixOS flake. diff --git a/flake.lock b/flake.lock index 774c899..9fc6ab5 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1754214453, - "narHash": "sha256-Q/I2xJn/j1wpkGhWkQnm20nShYnG7TI99foDBpXm1SY=", + "lastModified": 1764667669, + "narHash": "sha256-7WUCZfmqLAssbDqwg9cUDAXrSoXN79eEEq17qhTNM/Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5b09dc45f24cf32316283e62aec81ffee3c3e376", + "rev": "418468ac9527e799809c900eda37cbff999199b6", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 61d80cf..705814a 100644 --- a/flake.nix +++ b/flake.nix @@ -106,9 +106,9 @@ packages.${system} = { default = self.packages.${system}.cursor; cursor = buildCursor { - version = "1.6.35"; - url = "https://downloads.cursor.com/production/b753cece5c67c47cb5637199a5a5de2b7100c18f/linux/x64/Cursor-1.6.35-x86_64.AppImage"; - sha256 = "1qpkvs6zga979hhki49blyckffjp9pk49vhfn9nv57bxgjrbqszb"; + version = "2.2.43"; + url = "https://downloads.cursor.com/production/32cfbe848b35d9eb320980195985450f244b303d/linux/x64/Cursor-2.2.43-x86_64.AppImage"; + sha256 = "1bgifjyscqymbz0srw8np9pc88gwcccic3z4cnydyfskxhnyj0sr"; }; }; diff --git a/test-workflow-locally.sh b/test-workflow-locally.sh new file mode 100755 index 0000000..bc53ee7 --- /dev/null +++ b/test-workflow-locally.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash + +# Local test script for the GitHub Actions workflow +# This simulates what the workflow does without needing GitHub Actions + +set -e + +echo "=========================================" +echo "Testing Update Cursor Workflow Locally" +echo "=========================================" +echo "" + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' + +print_step() { echo -e "${BLUE}[STEP]${NC} $1"; } +print_success() { echo -e "${GREEN}[✓]${NC} $1"; } +print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } + +# Step 1: Check we're in the right directory +print_step "Checking repository..." +if [[ ! -f "flake.nix" ]] || [[ ! -f "update-cursor.sh" ]]; then + echo "Error: Must be run from the repository root" + exit 1 +fi +print_success "Repository check passed" +echo "" + +# Step 2: Check dependencies +print_step "Checking dependencies (like the workflow does)..." +missing=0 +for tool in curl htmlq rg nix-prefetch-url sed grep nix; do + if ! command -v "$tool" &> /dev/null; then + echo " ❌ Missing: $tool" + missing=1 + else + echo " ✓ Found: $tool" + fi +done + +if [[ "$missing" -eq 1 ]]; then + echo "" + print_warning "Some dependencies are missing. Install with:" + echo " nix-env -iA nixpkgs.curl nixpkgs.htmlq nixpkgs.ripgrep" + exit 1 +fi +print_success "All dependencies found" +echo "" + +# Step 3: Save current state +print_step "Saving current flake.nix state..." +cp flake.nix flake.nix.backup +ORIGINAL_VERSION=$(grep -o 'version = "[^"]*"' flake.nix | head -1 | sed 's/version = "//;s/"//') +print_success "Backed up (current version: $ORIGINAL_VERSION)" +echo "" + +# Step 4: Run the update script +print_step "Running update-cursor.sh..." +echo "" +if ./update-cursor.sh; then + UPDATE_SUCCESS=true +else + UPDATE_SUCCESS=false +fi +echo "" + +# Step 5: Check for changes +print_step "Checking for changes..." +if diff -q flake.nix flake.nix.backup > /dev/null 2>&1; then + print_success "No changes (already on latest version)" + CHANGED=false +else + NEW_VERSION=$(grep -o 'version = "[^"]*"' flake.nix | head -1 | sed 's/version = "//;s/"//') + print_success "Changes detected! Version: $ORIGINAL_VERSION → $NEW_VERSION" + CHANGED=true +fi +echo "" + +# Step 6: Show what would be committed +if [[ "$CHANGED" == true ]]; then + print_step "Changes that would be committed:" + echo "" + git diff flake.nix | head -n 50 + echo "" +fi + +# Step 7: Restore original state +print_step "Restoring original flake.nix..." +mv flake.nix.backup flake.nix +print_success "Restored to original state" +echo "" + +# Summary +echo "=========================================" +echo "Test Summary" +echo "=========================================" +echo "Update script: $([ "$UPDATE_SUCCESS" == true ] && echo "✓ Success" || echo "✗ Failed")" +echo "Changes detected: $([ "$CHANGED" == true ] && echo "Yes" || echo "No")" +echo "Workflow simulation: ✓ Complete" +echo "" +echo "The workflow would:" +if [[ "$CHANGED" == true ]]; then + echo " 1. Update flake.nix" + echo " 2. Commit with message: 'chore: update Cursor to version $NEW_VERSION'" + echo " 3. Push to GitHub" + echo " 4. Create release: v$NEW_VERSION" +else + echo " - Do nothing (no changes needed)" +fi +echo "" +print_success "Local test complete! Original state restored." + diff --git a/update-cursor.sh b/update-cursor.sh index f17ebd7..51cfce8 100755 --- a/update-cursor.sh +++ b/update-cursor.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Simple script to update Cursor version in a package-only flake +# Now with automatic link finding! set -e @@ -16,7 +17,30 @@ print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } -# Check if we're in the right directory +# 1. CHECK DEPENDENCIES +# ------------------------------------------------ +check_deps() { + print_info "Checking for required tools..." + local missing=0 + for tool in curl nix-prefetch-url sed grep; do + if ! command -v "$tool" &> /dev/null; then + print_error "Required tool '$tool' is not installed." + missing=1 + fi + done + + if [[ "$missing" -eq 1 ]]; then + print_error "Please install missing tools to continue." + print_info "You may be able to install them with: nix-shell -p curl nix" + exit 1 + fi + print_success "All required tools found." +} +check_deps +echo "" + +# 2. CHECK DIRECTORY +# ------------------------------------------------ if [[ ! -f "flake.nix" ]]; then print_error "This script must be run from the cursor-flake directory" exit 1 @@ -25,57 +49,84 @@ fi print_info "Cursor Package Flake Updater" echo "" -# Get current version and URL +# 3. GET CURRENT VALUES +# ------------------------------------------------ CURRENT_VERSION=$(grep -o 'version = "[^"]*"' flake.nix | head -1 | sed 's/version = "//;s/"//') -CURRENT_URL=$(grep -o 'https://downloads\.cursor\.com/[^"]*' flake.nix | head -1) +CURRENT_URL=$(grep -o 'https://downloads[.]cursor[.]com/[^"]*' flake.nix | head -1) CURRENT_HASH=$(grep -o 'sha256 = "[^"]*"' flake.nix | head -1 | sed 's/sha256 = "//;s/"//') print_info "Current version: ${CURRENT_VERSION:-unknown}" print_info "Current URL: $CURRENT_URL" echo "" -# Handle input -if [[ $# -ge 1 ]]; then - if [[ "$1" =~ ^https:// ]]; then - NEW_URL="$1" - NEW_VERSION=$(echo "$NEW_URL" | grep -o 'Cursor-[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1 | sed 's/Cursor-//') - else - NEW_VERSION="$1" - read -p "Enter the full download URL for version $NEW_VERSION: " NEW_URL - fi -else - read -p "Enter new version (e.g., 1.5.6) or full URL: " INPUT - if [[ "$INPUT" =~ ^https:// ]]; then - NEW_URL="$INPUT" - NEW_VERSION=$(echo "$NEW_URL" | grep -o 'Cursor-[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1 | sed 's/Cursor-//') - else - NEW_VERSION="$INPUT" - read -p "Enter the full download URL: " NEW_URL - fi +# 4. FIND LATEST URL (AUTOMATIC) +# ------------------------------------------------ +print_info "Finding latest AppImage URL from https://cursor.com/download..." + +# The download page now uses API URLs that redirect to the actual AppImage +# First, get the API URL from the download page +API_URL=$(curl -s https://cursor.com/download | \ + grep -o 'https://api2.cursor.sh/updates/download/golden/linux-x64/cursor/[^"]*' | \ + head -n 1) + +if [[ -z "$API_URL" ]]; then + print_error "Could not find API download URL on the download page." + print_error "The website structure may have changed." + exit 1 fi -if [[ -z "$NEW_URL" || -z "$NEW_VERSION" ]]; then - print_error "Invalid input" +print_info "Found API URL: $API_URL" + +# Follow the redirect to get the actual AppImage URL with version number +NEW_URL=$(curl -sIL "$API_URL" | grep -i "^location:" | tail -n 1 | sed 's/location: //i' | tr -d '\r\n') + +if [[ -z "$NEW_URL" ]]; then + print_error "Could not follow redirect to find actual AppImage URL." + print_error "The API endpoint may have changed." exit 1 fi +print_success "Found latest URL: $NEW_URL" + +# Check if it's actually a new URL +if [[ "$NEW_URL" == "$CURRENT_URL" ]]; then + print_success "You are already on the latest version ($CURRENT_VERSION)." + print_info "No update needed." + exit 0 +fi + +# Extract version from URL (e.g., .../Cursor-2.0.34-x86_64.AppImage -> 2.0.34) +NEW_VERSION=$(echo "$NEW_URL" | sed -n 's/.*Cursor-\(.*\)-x86_64\.AppImage/\1/p') + +if [[ -z "$NEW_VERSION" ]]; then + print_warning "Could not automatically determine new version from URL." + print_warning "The file name format may have changed." + # Fallback: ask user + read -p "Please enter the new version number: " NEW_VERSION + if [[ -z "$NEW_VERSION" ]]; then + print_error "Version number is required." + exit 1 + fi +fi + print_info "New version: $NEW_VERSION" -print_info "New URL: $NEW_URL" echo "" -# Get hash +# 5. GET HASH +# ------------------------------------------------ print_info "Fetching SHA256 hash..." HASH=$(nix-prefetch-url "$NEW_URL") if [[ -z "$HASH" ]]; then - print_error "Failed to get hash" + print_error "Failed to get hash for $NEW_URL" exit 1 fi print_success "SHA256 hash: $HASH" echo "" -# Update flake.nix +# 6. UPDATE FLAKE.NIX +# ------------------------------------------------ print_info "Updating flake.nix..." # Update version @@ -90,7 +141,8 @@ print_success "Updated URL" sed -i "s|sha256 = \"$CURRENT_HASH\";|sha256 = \"$HASH\";|" flake.nix print_success "Updated hash" -# Test build +# 7. TEST BUILD +# ------------------------------------------------ print_info "Testing build..." if nix build .#cursor; then print_success "Build successful!" @@ -120,10 +172,14 @@ if nix build .#cursor; then fi else print_error "Build failed!" + print_info "Reverting changes to flake.nix..." + # Simple git revert + git checkout -- flake.nix + print_success "flake.nix reverted." exit 1 fi echo "" print_info "Package updated successfully!" print_info "To use in your system: rebuild your main NixOS configuration" -print_success "Update complete!" +print_success "Update complete!" \ No newline at end of file