Skip to content

feat(auth): add actual login --device for browserless sign-in #887

feat(auth): add actual login --device for browserless sign-in

feat(auth): add actual login --device for browserless sign-in #887

Workflow file for this run

name: Build and Test
on:
pull_request:
branches: [main]
merge_group:
permissions: {}
env:
CARGO_INCREMENTAL: 0
jobs:
# === Build (release binaries for x86_64 + aarch64) ===
build:
name: Build
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Cache cargo
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ matrix.target }}-
- name: Build
run: cargo build --release --target ${{ matrix.target }}
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
- name: Upload artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: actual-${{ matrix.target }}
path: target/${{ matrix.target }}/release/actual
# === Test (debug mode, unit + integration tests) ===
test:
name: Test
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
- name: Cache cargo
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-test-
- name: Install semgrep
run: pip install semgrep
- name: Run tests
run: |
cargo test --workspace --features integration 2>&1 | tee test-output.txt
TEST_EXIT=${PIPESTATUS[0]}
echo "test_exit=$TEST_EXIT" >> $GITHUB_ENV
exit $TEST_EXIT
- name: Create test summary
if: always()
run: |
echo "## Test Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ env.test_exit }}" = "0" ]; then
PASSED=$(grep -c "^test .* ok$" test-output.txt 2>/dev/null || echo "0")
echo ":white_check_mark: **All $PASSED tests passed**" >> $GITHUB_STEP_SUMMARY
else
echo ":x: **Tests failed**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep -E "^(test .* FAILED|failures:)" test-output.txt >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "See full output" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi
- name: Upload test output
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-output
path: test-output.txt
- name: Upload tui-test captures
if: always()
uses: ./.github/actions/tui-test-report
# === Live E2E (uses pre-built binary from build job) ===
live-e2e:
name: Live E2E
needs: [test, build]
if: >-
always()
&& github.event_name == 'merge_group'
&& needs.test.result == 'success'
&& needs.build.result == 'success'
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Download actual binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: actual-x86_64-unknown-linux-gnu
path: ./bin
- name: Make binary executable
run: chmod +x ./bin/actual
- name: Install Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Verify Claude auth
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
claude auth status --json | grep -q '"loggedIn": *true'
- name: Run E2E
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
ACTUAL_E2E_API_URL: ${{ secrets.ACTUAL_E2E_API_URL }}
shell: bash
run: |
bash scripts/e2e.sh ./bin/actual 2>&1 | tee e2e-output.txt
E2E_EXIT=${PIPESTATUS[0]}
exit $E2E_EXIT
- name: Create test summary
if: always()
run: |
echo "## Live E2E Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ job.status }}" = "success" ]; then
PASSED=$(grep -c '\[PASS\]' e2e-output.txt 2>/dev/null || echo "0")
echo ":white_check_mark: **All $PASSED E2E checks passed**" >> $GITHUB_STEP_SUMMARY
else
echo ":x: **E2E failed**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep '\[FAIL\]' e2e-output.txt >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "See full output" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi
- name: Upload E2E output
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: e2e-output
path: e2e-output.txt
if-no-files-found: ignore