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
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!

View File

@@ -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}"