diff --git a/scripts/README.md b/scripts/README.md index 39066cb..8431357 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -2,11 +2,11 @@ ## test-ci-locally.sh -Tests the Gitea Actions workflow locally using `act` (nektos/act) in Docker. +Tests the CI workflow locally by running the **exact same docker-compose command** that the Gitea Actions workflow runs. ### Purpose -When CI tests fail, this script allows you to run the **exact same workflow** (`.gitea/workflows/magnitude.yml`) locally to debug issues without repeatedly pushing to trigger CI runs. It uses `nektos/act` to execute the workflow in a containerized environment, just like GitHub Actions or Gitea Actions would. +When CI tests fail, this script reproduces the exact CI environment locally to debug issues without repeatedly pushing to trigger CI runs. It runs `docker-compose.ci.yml` with the same parameters as the CI workflow, so you're testing in an identical environment. ### Usage @@ -14,58 +14,72 @@ When CI tests fail, this script allows you to run the **exact same workflow** (` ./scripts/test-ci-locally.sh ``` +Or run docker-compose directly (this is what the script does): + +```bash +docker compose -f docker-compose.ci.yml --profile test up \ + --abort-on-container-exit \ + --exit-code-from magnitude +``` + ### What it does -1. Loads environment variables from `.env` file -2. Runs `nektos/act:latest` Docker container with: - - Docker socket mounted (so act can create containers) - - Current directory mounted as workspace - - Secrets passed from `.env` file -3. Executes `.gitea/workflows/magnitude.yml` using act -4. The workflow then runs its steps: - - Checkout code - - Create .env file with secrets - - Run tests with docker-compose (starts SurrealDB, Next.js, Magnitude) - - Show logs on failure - - Upload test results - - Cleanup +1. Checks that `.env` file exists +2. Runs `docker compose -f docker-compose.ci.yml --profile test up` +3. This starts all services: + - **surrealdb**: In-memory database with health check + - **nextjs**: Node.js container running `pnpm dev` with health check + - **magnitude**: Playwright container running the test suite +4. Waits for tests to complete +5. Exits with magnitude's exit code +6. Shows service logs on failure +7. Cleans up containers and volumes ### Requirements -- Docker installed and running -- `.env` file with test credentials and secrets -- Docker socket accessible at `/var/run/docker.sock` +- Docker and docker-compose installed +- `.env` file with test credentials -### How It Works +### Services Architecture -The script uses `nektos/act` to execute the workflow YAML file. Act is compatible with both GitHub Actions and Gitea Actions workflows. It creates containers according to the workflow definition, which in turn uses `docker-compose.ci.yml` to set up the test environment: +The script starts a containerized test environment with proper health checks and dependencies: ``` -act (nektos/act Docker container) - ↓ executes .gitea/workflows/magnitude.yml - ↓ which runs docker-compose with: -magnitude (Playwright container) +magnitude (Playwright container - runs tests) ↓ depends on (waits for health check) -nextjs (Node.js container running pnpm dev) +nextjs (Node.js container - runs pnpm dev) ↓ depends on (waits for health check) -surrealdb (SurrealDB container) +surrealdb (SurrealDB container - in-memory mode) ``` -### Note on nektos/act vs gitea/act_runner +All services share the same network: +- Next.js accesses SurrealDB via `ws://surrealdb:8000/rpc` +- Magnitude accesses Next.js via `http://localhost:3000` -- `nektos/act` is designed for local workflow testing and is compatible with both GitHub Actions and Gitea Actions -- `gitea/act_runner` is a runner daemon that needs to connect to a Gitea instance and is not designed for offline local testing -- This script uses `nektos/act` which provides the local testing experience similar to running workflows in CI +### Why This Approach? + +This is simpler and more accurate than using workflow runner tools like `act` or `act_runner` because: + +1. **Identical to CI**: The CI workflow (`.gitea/workflows/magnitude.yml`) literally runs this docker-compose command, so you're testing the exact same thing +2. **No Additional Tools**: Doesn't require `act`, `act_runner`, or any workflow execution tools +3. **Direct Debugging**: Runs the actual test commands directly, making it easier to see what's happening +4. **Faster**: No overhead from workflow interpretation or runner setup ### Debugging CI Failures If Gitea Actions fail: 1. Check the workflow logs for errors in Gitea UI -2. Run `./scripts/test-ci-locally.sh` to execute the workflow locally -3. The script will show the same steps and output as CI -4. Fix issues based on the local test results -5. Run script again to verify fix -6. Commit and push once tests pass locally +2. Run `./scripts/test-ci-locally.sh` to reproduce **exactly** +3. The script will show the same output as CI +4. Debug with docker-compose logs if needed: + ```bash + docker compose -f docker-compose.ci.yml logs surrealdb + docker compose -f docker-compose.ci.yml logs nextjs + docker compose -f docker-compose.ci.yml logs magnitude + ``` +5. Fix issues locally +6. Run script again to verify fix +7. Commit and push once tests pass locally -This is **much** faster than debugging via CI push cycles and gives you the exact same environment! +This is **much** faster than debugging via CI push cycles and gives you identical results! diff --git a/scripts/test-ci-locally.sh b/scripts/test-ci-locally.sh index d65b9e3..c18d876 100755 --- a/scripts/test-ci-locally.sh +++ b/scripts/test-ci-locally.sh @@ -1,11 +1,11 @@ #!/bin/bash -# Script to test Gitea Actions workflow locally using act (nektos/act) -# This runs the actual .gitea/workflows/magnitude.yml file in a containerized environment +# Script to test CI workflow locally by running the exact same docker-compose command as CI +# This runs docker-compose.ci.yml which is what the Gitea Actions workflow uses set -e # Exit on error echo "=========================================" -echo "Testing Gitea Actions Workflow Locally" +echo "Testing CI Workflow Locally" echo "=========================================" # Colors for output @@ -21,42 +21,42 @@ if [ ! -f .env ]; then exit 1 fi -# Load environment variables from .env for passing as secrets -echo -e "${YELLOW}Loading environment variables from .env${NC}" -export $(cat .env | grep -v '^#' | xargs) +echo -e "${YELLOW}Running the exact same docker-compose command as CI${NC}" +echo -e "${YELLOW}This executes: docker compose -f docker-compose.ci.yml --profile test up${NC}" +echo "" -# Build secret flags for act -# These will be available in the workflow as secrets.* -SECRET_FLAGS="" -SECRET_FLAGS="$SECRET_FLAGS -s ATPROTO_CLIENT_ID=$ATPROTO_CLIENT_ID" -SECRET_FLAGS="$SECRET_FLAGS -s ATPROTO_REDIRECT_URI=$ATPROTO_REDIRECT_URI" -SECRET_FLAGS="$SECRET_FLAGS -s GOOGLE_API_KEY=$GOOGLE_API_KEY" -SECRET_FLAGS="$SECRET_FLAGS -s DEEPGRAM_API_KEY=$DEEPGRAM_API_KEY" -SECRET_FLAGS="$SECRET_FLAGS -s SURREAL_JWT_SECRET=$SURREAL_JWT_SECRET" -SECRET_FLAGS="$SECRET_FLAGS -s TEST_BLUESKY_HANDLE=$TEST_BLUESKY_HANDLE" -SECRET_FLAGS="$SECRET_FLAGS -s TEST_BLUESKY_PASSWORD=$TEST_BLUESKY_PASSWORD" -SECRET_FLAGS="$SECRET_FLAGS -s ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" +# Cleanup function +cleanup() { + echo -e "${YELLOW}Cleaning up containers and volumes...${NC}" + docker compose -f docker-compose.ci.yml down -v +} -echo -e "${YELLOW}Running Gitea Actions workflow with act (nektos/act)${NC}" -echo -e "${YELLOW}This will execute .gitea/workflows/magnitude.yml${NC}" +# Trap cleanup on exit +trap cleanup EXIT -# Run act in Docker to execute the workflow -# - Mount Docker socket so act can create containers -# - Mount current directory as workspace -# - Pass secrets as flags -# - Use -W flag to specify workflow file -# - Use --rm to clean up container after run -docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v "$(pwd):/workspace" \ - -w /workspace \ - nektos/act:latest \ - -W .gitea/workflows/magnitude.yml \ - $SECRET_FLAGS || { - echo -e "${RED}Workflow execution failed!${NC}" +# Run the exact same command that CI runs +docker compose -f docker-compose.ci.yml --profile test up \ + --abort-on-container-exit \ + --exit-code-from magnitude || { + echo "" + echo -e "${RED}=========================================${NC}" + echo -e "${RED}Tests failed!${NC}" + echo -e "${RED}=========================================${NC}" + echo "" + echo -e "${YELLOW}Showing service logs:${NC}" + echo "" + echo "=== SurrealDB Logs ===" + docker compose -f docker-compose.ci.yml logs --tail=50 surrealdb + echo "" + echo "=== Next.js Logs ===" + docker compose -f docker-compose.ci.yml logs --tail=50 nextjs + echo "" + echo "=== Magnitude Logs ===" + docker compose -f docker-compose.ci.yml logs --tail=50 magnitude exit 1 } +echo "" echo -e "${GREEN}=========================================${NC}" -echo -e "${GREEN}Workflow executed successfully!${NC}" +echo -e "${GREEN}All tests passed!${NC}" echo -e "${GREEN}=========================================${NC}"