name: Tests on: pull_request: branches: - main - releases/** push: branches: - main - releases/** permissions: contents: read jobs: # Build and unit test build: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Node.js 24.x uses: actions/setup-node@v4 with: node-version: 24.x cache: npm - run: npm ci - name: Prettier Format Check run: npm run format-check - name: ESLint Check run: npm run lint - name: Build & Test run: npm run test # End to end save and restore test-save: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v5 - name: Generate files in working directory shell: bash run: __tests__/create-cache-files.sh ${{ runner.os }} test-cache - name: Generate files outside working directory shell: bash run: __tests__/create-cache-files.sh ${{ runner.os }} ~/test-cache - name: Save cache uses: ./ with: key: test-${{ runner.os }}-${{ github.run_id }} path: | test-cache ~/test-cache test-restore: needs: test-save strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] fail-fast: false runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v5 - name: Restore cache uses: ./ with: key: test-${{ runner.os }}-${{ github.run_id }} path: | test-cache ~/test-cache - name: Verify cache files in working directory shell: bash run: __tests__/verify-cache-files.sh ${{ runner.os }} test-cache - name: Verify cache files outside working directory shell: bash run: __tests__/verify-cache-files.sh ${{ runner.os }} ~/test-cache # End to end with proxy test-proxy-save: runs-on: ubuntu-latest container: image: ubuntu:latest options: --privileged services: squid-proxy: image: ubuntu/squid:latest ports: - 3128:3128 env: http_proxy: http://squid-proxy:3128 https_proxy: http://squid-proxy:3128 HTTP_PROXY: http://squid-proxy:3128 HTTPS_PROXY: http://squid-proxy:3128 steps: - name: Checkout uses: actions/checkout@v5 - name: Install iptables run: | apt-get update apt-get install -y iptables dnsutils - name: Block direct internet access (enforce proxy) run: | # Get squid-proxy IP address PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }') echo "Proxy IP: $PROXY_IP" # Allow established connections iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow loopback iptables -A OUTPUT -o lo -j ACCEPT # Allow connections to the proxy iptables -A OUTPUT -d $PROXY_IP -p tcp --dport 3128 -j ACCEPT # Allow DNS (needed for proxy to resolve hostnames) iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT # Block all other outbound HTTP/HTTPS traffic iptables -A OUTPUT -p tcp --dport 80 -j REJECT iptables -A OUTPUT -p tcp --dport 443 -j REJECT echo "iptables rules applied:" iptables -L OUTPUT -n -v - name: Verify direct connections are blocked run: | # This should fail - direct HTTPS connection without proxy if curl --connect-timeout 5 --max-time 10 --noproxy '*' https://github.com 2>/dev/null; then echo "ERROR: Direct connection succeeded but should have been blocked!" exit 1 else echo "Direct connection correctly blocked" fi - name: Generate files run: __tests__/create-cache-files.sh proxy test-cache - name: Save cache uses: ./ with: key: test-proxy-${{ github.run_id }} path: test-cache test-proxy-restore: needs: test-proxy-save runs-on: ubuntu-latest container: image: ubuntu:latest options: --privileged services: squid-proxy: image: ubuntu/squid:latest ports: - 3128:3128 env: http_proxy: http://squid-proxy:3128 https_proxy: http://squid-proxy:3128 HTTP_PROXY: http://squid-proxy:3128 HTTPS_PROXY: http://squid-proxy:3128 steps: - name: Checkout uses: actions/checkout@v5 - name: Install iptables run: | apt-get update apt-get install -y iptables dnsutils - name: Block direct internet access (enforce proxy) run: | # Get squid-proxy IP address PROXY_IP=$(getent hosts squid-proxy | awk '{ print $1 }') echo "Proxy IP: $PROXY_IP" # Allow established connections iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow loopback iptables -A OUTPUT -o lo -j ACCEPT # Allow connections to the proxy iptables -A OUTPUT -d $PROXY_IP -p tcp --dport 3128 -j ACCEPT # Allow DNS (needed for proxy to resolve hostnames) iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT # Block all other outbound HTTP/HTTPS traffic iptables -A OUTPUT -p tcp --dport 80 -j REJECT iptables -A OUTPUT -p tcp --dport 443 -j REJECT echo "iptables rules applied:" iptables -L OUTPUT -n -v - name: Verify direct connections are blocked run: | # This should fail - direct HTTPS connection without proxy if curl --connect-timeout 5 --max-time 10 --noproxy '*' https://github.com 2>/dev/null; then echo "ERROR: Direct connection succeeded but should have been blocked!" exit 1 else echo "Direct connection correctly blocked" fi - name: Restore cache uses: ./ with: key: test-proxy-${{ github.run_id }} path: test-cache - name: Verify cache run: __tests__/verify-cache-files.sh proxy test-cache