refactor: Simplify CI testing to use docker-compose directly

Instead of trying to use workflow runner tools (act/act_runner), the script
now directly runs the docker-compose command that CI uses. This is:

- More accurate (exact same command as CI)
- Simpler (no additional tools needed)
- Faster (no workflow interpretation overhead)
- Easier to debug (direct access to service logs)

The CI workflow literally runs `docker compose -f docker-compose.ci.yml`, so
running that locally is the most accurate way to test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-10 14:12:35 +00:00
parent 9df7278d55
commit bb650a3ed9
2 changed files with 84 additions and 70 deletions

View File

@@ -2,11 +2,11 @@
## test-ci-locally.sh ## 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 ### 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 ### Usage
@@ -14,58 +14,72 @@ When CI tests fail, this script allows you to run the **exact same workflow** (`
./scripts/test-ci-locally.sh ./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 ### What it does
1. Loads environment variables from `.env` file 1. Checks that `.env` file exists
2. Runs `nektos/act:latest` Docker container with: 2. Runs `docker compose -f docker-compose.ci.yml --profile test up`
- Docker socket mounted (so act can create containers) 3. This starts all services:
- Current directory mounted as workspace - **surrealdb**: In-memory database with health check
- Secrets passed from `.env` file - **nextjs**: Node.js container running `pnpm dev` with health check
3. Executes `.gitea/workflows/magnitude.yml` using act - **magnitude**: Playwright container running the test suite
4. The workflow then runs its steps: 4. Waits for tests to complete
- Checkout code 5. Exits with magnitude's exit code
- Create .env file with secrets 6. Shows service logs on failure
- Run tests with docker-compose (starts SurrealDB, Next.js, Magnitude) 7. Cleans up containers and volumes
- Show logs on failure
- Upload test results
- Cleanup
### Requirements ### Requirements
- Docker installed and running - Docker and docker-compose installed
- `.env` file with test credentials and secrets - `.env` file with test credentials
- Docker socket accessible at `/var/run/docker.sock`
### 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) magnitude (Playwright container - runs tests)
↓ executes .gitea/workflows/magnitude.yml
↓ which runs docker-compose with:
magnitude (Playwright container)
↓ depends on (waits for health check) ↓ 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) ↓ 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 ### Why This Approach?
- `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 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 ### Debugging CI Failures
If Gitea Actions fail: If Gitea Actions fail:
1. Check the workflow logs for errors in Gitea UI 1. Check the workflow logs for errors in Gitea UI
2. Run `./scripts/test-ci-locally.sh` to execute the workflow locally 2. Run `./scripts/test-ci-locally.sh` to reproduce **exactly**
3. The script will show the same steps and output as CI 3. The script will show the same output as CI
4. Fix issues based on the local test results 4. Debug with docker-compose logs if needed:
5. Run script again to verify fix ```bash
6. Commit and push once tests pass locally 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!

View File

@@ -1,11 +1,11 @@
#!/bin/bash #!/bin/bash
# Script to test Gitea Actions workflow locally using act (nektos/act) # Script to test CI workflow locally by running the exact same docker-compose command as CI
# This runs the actual .gitea/workflows/magnitude.yml file in a containerized environment # This runs docker-compose.ci.yml which is what the Gitea Actions workflow uses
set -e # Exit on error set -e # Exit on error
echo "=========================================" echo "========================================="
echo "Testing Gitea Actions Workflow Locally" echo "Testing CI Workflow Locally"
echo "=========================================" echo "========================================="
# Colors for output # Colors for output
@@ -21,42 +21,42 @@ if [ ! -f .env ]; then
exit 1 exit 1
fi fi
# Load environment variables from .env for passing as secrets echo -e "${YELLOW}Running the exact same docker-compose command as CI${NC}"
echo -e "${YELLOW}Loading environment variables from .env${NC}" echo -e "${YELLOW}This executes: docker compose -f docker-compose.ci.yml --profile test up${NC}"
export $(cat .env | grep -v '^#' | xargs) echo ""
# Build secret flags for act # Cleanup function
# These will be available in the workflow as secrets.* cleanup() {
SECRET_FLAGS="" echo -e "${YELLOW}Cleaning up containers and volumes...${NC}"
SECRET_FLAGS="$SECRET_FLAGS -s ATPROTO_CLIENT_ID=$ATPROTO_CLIENT_ID" docker compose -f docker-compose.ci.yml down -v
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"
echo -e "${YELLOW}Running Gitea Actions workflow with act (nektos/act)${NC}" # Trap cleanup on exit
echo -e "${YELLOW}This will execute .gitea/workflows/magnitude.yml${NC}" trap cleanup EXIT
# Run act in Docker to execute the workflow # Run the exact same command that CI runs
# - Mount Docker socket so act can create containers docker compose -f docker-compose.ci.yml --profile test up \
# - Mount current directory as workspace --abort-on-container-exit \
# - Pass secrets as flags --exit-code-from magnitude || {
# - Use -W flag to specify workflow file echo ""
# - Use --rm to clean up container after run echo -e "${RED}=========================================${NC}"
docker run --rm \ echo -e "${RED}Tests failed!${NC}"
-v /var/run/docker.sock:/var/run/docker.sock \ echo -e "${RED}=========================================${NC}"
-v "$(pwd):/workspace" \ echo ""
-w /workspace \ echo -e "${YELLOW}Showing service logs:${NC}"
nektos/act:latest \ echo ""
-W .gitea/workflows/magnitude.yml \ echo "=== SurrealDB Logs ==="
$SECRET_FLAGS || { docker compose -f docker-compose.ci.yml logs --tail=50 surrealdb
echo -e "${RED}Workflow execution failed!${NC}" 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 exit 1
} }
echo ""
echo -e "${GREEN}=========================================${NC}" echo -e "${GREEN}=========================================${NC}"
echo -e "${GREEN}Workflow executed successfully!${NC}" echo -e "${GREEN}All tests passed!${NC}"
echo -e "${GREEN}=========================================${NC}" echo -e "${GREEN}=========================================${NC}"