Skip to content

Commit dd94878

Browse files
savilclaude
andauthored
Fix GitHub API rate limiting in cli-tests (#2731)
## Problem The cli-tests on the `main` branch have been failing intermittently in GitHub Actions since at least October 7, 2025, due to GitHub API rate limiting when Nix attempts to fetch nixpkgs metadata. ### Error Message ``` unable to download 'https://api.github.com/repos/NixOS/nixpkgs/commits/nixpkgs-unstable': HTTP error 403 API rate limit exceeded for 13.105.49.133. ``` Despite having `GITHUB_TOKEN` configured in both `NIX_CONFIG` environment variable and `~/.config/nix/nix.conf`, the tests were still hitting unauthenticated rate limits. ## Root Cause On macOS runners, the Nix daemon: - Runs as a different user (not the runner user) - Reads `/etc/nix/nix.conf` instead of the user's `~/.config/nix/nix.conf` - Doesn't inherit environment variables from the runner This meant that while `nix show-config` showed the access token was configured, the daemon wasn't actually using it when making GitHub API requests. ## Solution This PR implements a two-pronged approach: ### 1. Configure Nix Daemon Properly (Primary Fix) - On macOS runners, configure `/etc/nix/nix.conf` with the GitHub token - Ensure the directory and file exist before writing - Restart the Nix daemon to pick up the new configuration - In `auto-nix-install` job, configure AFTER Nix is installed (not before) ### 2. Pass Token via Command-Line Options (Backup) - Modify `internal/nix/command.go` to pass `--option access-tokens github.com=$GITHUB_TOKEN` in all nix commands - This ensures the token is used even if config files aren't picked up properly ## Changes - `.github/workflows/cli-tests.yaml`: - Update "Setup Nix GitHub authentication" step to ensure `/etc/nix/nix.conf` exists before writing - Reorder `auto-nix-install` job to configure Nix AFTER installation completes - `internal/nix/command.go`: Add GITHUB_TOKEN to nix command args as --option access-tokens ## Detailed Analysis For a comprehensive diagnostic report with evidence, timeline, and alternative solutions considered, see: **[CLI Tests Failure Report](https://gist.github.com/savil/e8a527aa70e38ab588a1bd46103123bd)** ## Note on Reproduction The issue is specific to GitHub Actions environment and cannot be easily reproduced locally: - Requires GitHub Actions runner IP pool hitting rate limits - Intermittent based on shared quota across GitHub Actions - Depends on macOS Nix daemon configuration This PR validates the fix directly in CI/CD where the issue occurs. Fixes the intermittent test failures that have been occurring since October 7, 2025. --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 75f7e56 commit dd94878

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

.github/workflows/cli-tests.yaml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,25 @@ jobs:
181181
- name: Setup Nix GitHub authentication
182182
run: |
183183
# Setup github authentication to ensure Github's rate limits are not hit
184+
# For macOS, we need to configure the system-wide nix.conf because the Nix daemon
185+
# runs as a different user and doesn't read the user's ~/.config/nix/nix.conf
186+
if [ "$RUNNER_OS" == "macOS" ]; then
187+
echo "Configuring system-wide Nix config for macOS daemon"
188+
# Ensure /etc/nix directory exists
189+
if [ ! -d /etc/nix ]; then
190+
sudo mkdir -p /etc/nix
191+
fi
192+
# Check if file exists, create it if not
193+
if [ ! -f /etc/nix/nix.conf ]; then
194+
echo "# Nix configuration" | sudo tee /etc/nix/nix.conf > /dev/null
195+
fi
196+
echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" | sudo tee -a /etc/nix/nix.conf
197+
# Restart nix daemon to pick up the new configuration
198+
sudo launchctl stop org.nixos.nix-daemon || true
199+
sudo launchctl start org.nixos.nix-daemon || true
200+
sleep 2 # Give daemon time to restart
201+
fi
202+
# For Linux and as a backup for macOS, also configure user config
184203
mkdir -p ~/.config/nix
185204
echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" > ~/.config/nix/nix.conf
186205
- name: Run fast tests
@@ -222,12 +241,28 @@ jobs:
222241
export NIX_INSTALLER_NO_CHANNEL_ADD=1
223242
export DEVBOX_FEATURE_DETSYS_INSTALLER=${{ matrix.use-detsys }}
224243
225-
# Setup github authentication to ensure Github's rate limits are not hit.
226-
# If this works, we can consider refactoring this into a reusable github action helper.
244+
# Setup github authentication BEFORE running devbox to ensure Github's rate limits are not hit.
245+
# Configure user config first (Nix installer will respect this)
227246
mkdir -p ~/.config/nix
228247
echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" > ~/.config/nix/nix.conf
229248
249+
# Run devbox which will auto-install Nix if needed
230250
devbox run echo "Installing packages..."
251+
252+
# After Nix is installed, configure system-wide config for the daemon on macOS
253+
if [ "$RUNNER_OS" == "macOS" ]; then
254+
echo "Configuring system-wide Nix config for macOS daemon"
255+
# Check if file exists, create directory if needed
256+
if [ ! -f /etc/nix/nix.conf ]; then
257+
sudo mkdir -p /etc/nix
258+
echo "# Nix configuration" | sudo tee /etc/nix/nix.conf > /dev/null
259+
fi
260+
echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" | sudo tee -a /etc/nix/nix.conf
261+
# Restart nix daemon to pick up the new configuration
262+
sudo launchctl stop org.nixos.nix-daemon || true
263+
sudo launchctl start org.nixos.nix-daemon || true
264+
sleep 2 # Give daemon time to restart
265+
fi
231266
- name: Test removing package
232267
run: devbox rm go
233268

internal/nix/command.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
package nix
22

3+
import "os"
4+
35
func init() {
46
Default.ExtraArgs = Args{
57
"--extra-experimental-features", "ca-derivations",
68
"--option", "experimental-features", "nix-command flakes fetch-closure",
79
}
10+
11+
// Add GitHub access token if available to avoid rate limiting
12+
// This is a backup in case the config file isn't picked up properly
13+
if token := os.Getenv("GITHUB_TOKEN"); token != "" {
14+
Default.ExtraArgs = append(Default.ExtraArgs,
15+
"--option", "access-tokens", "github.com="+token)
16+
}
817
}
918

1019
func appendArgs[E any](args Args, new []E) Args {

0 commit comments

Comments
 (0)