diff --git a/.gitignore b/.gitignore index 6d06257bf8d6..280f5ee209a3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ back-secret.env front-secret.env .envrc +# Per-worktree compose override (WORKTREE_PREFIX), written by `make configure-worktree` +/.env + # Legacy .env filenames .env-back .env-front diff --git a/Makefile b/Makefile index 38206bcc6fca..d34f3fa4e015 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build reset-dev-env claude-setup migrate be-up be-up-debug be-up-fake-sso fe-up up up-fake-sso c rails-console rails-console-exec e2e-setup e2e-setup-and-up e2e-setup-and-up-fake-sso e2e-run-test e2e-ci-env-setup e2e-ci-env-setup-and-up e2e-ci-env-run-test ci-regenerate-templates ci-trigger-build ci-run-e2e release_pr +.PHONY: build reset-dev-env claude-setup configure-worktree migrate be-up be-up-debug be-up-fake-sso fe-up up up-fake-sso c rails-console rails-console-exec e2e-setup e2e-setup-and-up e2e-setup-and-up-fake-sso e2e-run-test e2e-ci-env-setup e2e-ci-env-setup-and-up e2e-ci-env-run-test ci-regenerate-templates ci-trigger-build ci-run-e2e release_pr # You can run this file with `make` command: # make reset-dev-env @@ -32,6 +32,36 @@ reset-dev-env: claude-setup: @bin/setup-claude +# For git worktrees: seed the gitignored *-secret.env files from the main checkout, install +# front-end deps, write a root .env with WORKTREE_PREFIX (derived from this worktree's folder +# name) so the stack gets its own container/network names and doesn't clash with other +# worktrees, then reset the dev env (reset-dev-env handles the Claude overlay setup, image +# build, and DB reset). Only works if the worktree is created in the same folder as the main +# checkout (../citizenlab). +configure-worktree: + @gitdir="$$(git rev-parse --git-dir 2>/dev/null)"; \ + commondir="$$(git rev-parse --git-common-dir 2>/dev/null)"; \ + if [ -z "$$gitdir" ]; then \ + echo "configure-worktree: not inside a git repository. Aborting."; exit 1; \ + elif [ "$$gitdir" = "$$commondir" ]; then \ + echo "configure-worktree: this is the main checkout, not a linked git worktree. Aborting."; exit 1; \ + fi + @for f in $$(cd ../citizenlab/env_files && ls *-secret.env 2>/dev/null); do \ + if [ ! -e env_files/$$f ]; then \ + cp ../citizenlab/env_files/$$f env_files/$$f && echo "Copied env_files/$$f from ../citizenlab"; \ + else \ + echo "Skipping env_files/$$f (already exists)"; \ + fi; \ + done + cd front && npm install + @prefix=$$(basename "$$PWD" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_-]/-/g'); \ + if [ -f .env ] && grep -q '^WORKTREE_PREFIX=' .env; then \ + sed -i.bak "s/^WORKTREE_PREFIX=.*/WORKTREE_PREFIX=$$prefix/" .env && rm -f .env.bak && echo "Updated WORKTREE_PREFIX=$$prefix in .env"; \ + else \ + echo "WORKTREE_PREFIX=$$prefix" >> .env && echo "Set WORKTREE_PREFIX=$$prefix in .env"; \ + fi + make reset-dev-env + migrate: docker compose run --rm web bin/rails db:migrate cl2back:clean_tenant_settings email_campaigns:assure_campaign_records fix_existing_tenants:update_permissions cl2back:clear_cache_store email_campaigns:remove_deprecated @@ -208,12 +238,12 @@ sso-reset: # # or # make rails-console c rails-console: - docker compose run --rm web bin/rails c + docker compose exec web bin/rails c # Runs rails console in an existing web container. May be useful if you need to access localhost:4000 in the console. # E.g., this command works in this console `curl http://localhost:4000` rails-console-exec: - docker exec -it "$$(docker ps | awk '/cl-back-web/ {print $$1}' | head -1)" bin/rails c + docker compose exec web bin/rails c # search_path=localhost specifies the schema of localhost tenant psql: @@ -235,7 +265,7 @@ r rspec: # SSH session onto the running web container. bash-exec: - docker exec -it cl-back-web /bin/bash + docker compose exec web /bin/bash # Usage examples: # make feature-flag feature=initiative_cosponsors enabled=true diff --git a/docker-compose.yml b/docker-compose.yml index f6f8df7f0b6a..cd963e89e4e7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,8 +15,10 @@ services: volumes: - "postgres:/var/lib/postgresql/data" + # NOTE: WORKTREE_PREFIX is an env var that can be set when running in a git worktree + # to allow independent containers per worktree (though they cannot run simultaneously due to port conflicts) web: - container_name: cl-back-web + container_name: ${WORKTREE_PREFIX:-cl}-back-web depends_on: - "postgres" - "mailcatcher" @@ -47,7 +49,7 @@ services: stdin_open: true que: - container_name: cl-que + container_name: ${WORKTREE_PREFIX:-cl}-que depends_on: - "postgres" - "mailcatcher" @@ -74,7 +76,7 @@ services: stdin_open: true rabbitmq: - container_name: cl-back-rabbit + container_name: ${WORKTREE_PREFIX:-cl}-back-rabbit image: "rabbitmq:3.8-management" ports: - "8088:15672" @@ -95,7 +97,7 @@ services: # Open API documentation - Only starts if you run docker compose --profile openapi up openapi: - container_name: cl-open-api + container_name: ${WORKTREE_PREFIX:-cl}-open-api image: swaggerapi/swagger-ui ports: - 8080:8080 @@ -108,7 +110,7 @@ services: # For generating PDFs gotenberg: - container_name: cl-gotenberg + container_name: ${WORKTREE_PREFIX:-cl}-gotenberg image: gotenberg/gotenberg:8.21 restart: always @@ -125,7 +127,7 @@ services: fake_sso: # Distinct from the standalone fake_sso/docker-compose.yml (which uses # `cl-fake-sso`) so the two stacks can coexist without conflicting. - container_name: cl-fake-sso-app + container_name: ${WORKTREE_PREFIX:-cl}-fake-sso-app image: node:22-alpine working_dir: /app ports: @@ -147,7 +149,7 @@ services: # Front-end dev server - Only starts if you run docker compose --profile frontend up front: - container_name: cl-front + container_name: ${WORKTREE_PREFIX:-cl}-front image: node:24.15.0 working_dir: /citizenlab/front command: sh -c "npm install && npm start" @@ -177,4 +179,4 @@ volumes: networks: default: - name: citizenlab + name: ${WORKTREE_PREFIX:-citizenlab}