diff --git a/.github/actions/prep-apt/action.yml b/.github/actions/prep-apt/action.yml new file mode 100644 index 000000000..49afa3622 --- /dev/null +++ b/.github/actions/prep-apt/action.yml @@ -0,0 +1,43 @@ +name: Install Playwright system dependencies +description: > + Stops background apt services, waits for dpkg/apt locks to clear, then + installs Playwright system dependencies with retry logic. Intended for + self-hosted Linux runners where unattended-upgrades can cause intermittent + apt lock contention or mirror-sync failures. + +runs: + using: composite + steps: + - name: Stop background apt services + shell: bash + run: | + sudo systemctl stop unattended-upgrades apt-daily.service apt-daily-upgrade.service 2>/dev/null || true + echo "Waiting for apt locks to clear..." + timeout 120 bash -c ' + while sudo fuser /var/lib/dpkg/lock /var/lib/dpkg/lock-frontend \ + /var/lib/apt/lists/lock /var/cache/apt/archives/lock \ + 2>/dev/null; do + echo " apt lock held, retrying in 5s..." + sleep 5 + done + ' || { + echo "Lock wait timed out — force-killing lock holders" + sudo fuser -k /var/lib/dpkg/lock /var/lib/dpkg/lock-frontend \ + /var/lib/apt/lists/lock /var/cache/apt/archives/lock 2>/dev/null || true + sudo dpkg --configure -a 2>/dev/null || true + } + + - name: Install Playwright system dependencies (with retry) + shell: bash + run: | + for attempt in 1 2 3; do + echo "Attempt $attempt: npx playwright install-deps" + npx playwright install-deps && break + if [ $attempt -lt 3 ]; then + echo "Failed, retrying in 15s..." + sleep 15 + else + echo "All attempts failed" + exit 1 + fi + done diff --git a/.github/workflows/run-nala-daily.yml b/.github/workflows/run-nala-daily.yml index 4a3016303..539bcd243 100644 --- a/.github/workflows/run-nala-daily.yml +++ b/.github/workflows/run-nala-daily.yml @@ -45,12 +45,16 @@ jobs: - name: Cache Playwright browsers uses: actions/cache@v4 id: playwright-cache + continue-on-error: true with: path: ~/.cache/ms-playwright key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.js') }} - - name: Install Playwright dependencies - run: npx playwright install --with-deps + - name: Install Playwright system dependencies + uses: ./.github/actions/prep-apt + + - name: Install Playwright browsers + run: npx playwright install - name: Set execute permission for gh.run.sh run: chmod +x ./nala/utils/gh.run.sh diff --git a/.github/workflows/run-nala-milolibs.yaml b/.github/workflows/run-nala-milolibs.yaml index 4c0bf2d64..74ef7ee55 100644 --- a/.github/workflows/run-nala-milolibs.yaml +++ b/.github/workflows/run-nala-milolibs.yaml @@ -49,12 +49,16 @@ jobs: - name: Cache Playwright browsers uses: actions/cache@v4 id: playwright-cache + continue-on-error: true with: path: ~/.cache/ms-playwright key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.js') }} - - name: Install Playwright dependencies - run: npx playwright install --with-deps + - name: Install Playwright system dependencies + uses: ./.github/actions/prep-apt + + - name: Install Playwright browsers + run: npx playwright install - name: Set environment variables run: | diff --git a/.github/workflows/run-nala.yml b/.github/workflows/run-nala.yml index 175046219..bff04b44e 100644 --- a/.github/workflows/run-nala.yml +++ b/.github/workflows/run-nala.yml @@ -65,7 +65,7 @@ jobs: key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.js') }} - name: Install Playwright system dependencies - run: npx playwright install-deps + uses: ./.github/actions/prep-apt - name: Install/verify Playwright browsers run: | @@ -162,6 +162,8 @@ jobs: path: ~/.cache/ms-playwright key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.js') }} + # Docs tests run on GitHub-hosted runners (ubuntu-latest) — no unattended-upgrades + # lock contention, so the prep-apt composite action is not needed here. - name: Install Playwright system dependencies if: steps.playwright-cache.outputs.cache-hit != 'true' run: npx playwright install-deps