Spaces:
Build error
Build error
| name: CI Docker | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| changed-files-check: | |
| uses: ./.github/workflows/changed-files.yaml | |
| with: | |
| files: | | |
| packages/twenty-docker/** | |
| docker-compose.yml | |
| test-compose: | |
| needs: changed-files-check | |
| if: needs.changed-files-check.outputs.any_changed == 'true' | |
| timeout-minutes: 30 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| # Pull base images through Google's Docker Hub mirror — avoids Docker Hub | |
| # rate limits and needs no credentials (this repo is public). | |
| - name: Configure Docker Hub mirror | |
| run: | | |
| echo '{"registry-mirrors":["https://mirror.gcr.io"]}' | sudo tee /etc/docker/daemon.json | |
| sudo systemctl restart docker | |
| - name: Run compose | |
| run: | | |
| echo "Patching docker-compose.yml..." | |
| yq eval 'del(.services.server.image)' -i docker-compose.yml | |
| yq eval '.services.server.build.context = "../../"' -i docker-compose.yml | |
| yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i docker-compose.yml | |
| yq eval '.services.server.build.target = "twenty"' -i docker-compose.yml | |
| yq eval '.services.server.restart = "no"' -i docker-compose.yml | |
| echo "Setting up .env file..." | |
| cp .env.example .env | |
| echo "Generating secrets..." | |
| echo "" >> .env | |
| echo "# === Randomly generated secrets ===" >>.env | |
| echo "APP_SECRET=$(openssl rand -base64 32)" >>.env | |
| echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env | |
| echo "Docker compose up..." | |
| docker compose up -d || { | |
| echo "Docker compose failed to start" | |
| docker compose logs | |
| exit 1 | |
| } | |
| docker compose logs db server -f & | |
| pid=$! | |
| echo "Waiting for database to start..." | |
| count=0 | |
| while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ]; do | |
| sleep 1; | |
| count=$((count+1)); | |
| if [ $(docker inspect --format='{{.State.Status}}' twenty-db-1) = "exited" ]; then | |
| echo "Database exited" | |
| docker compose logs db | |
| exit 1 | |
| fi | |
| if [ $count -gt 300 ]; then | |
| echo "Failed to start database after 5 minutes" | |
| docker compose logs db | |
| exit 1 | |
| fi | |
| echo "Still waiting for database... (${count}/60)" | |
| done | |
| echo "Waiting for server to start..." | |
| count=0 | |
| while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do | |
| sleep 1; | |
| count=$((count+1)); | |
| if [ $(docker inspect --format='{{.State.Status}}' twenty-server-1) = "exited" ]; then | |
| echo "Server exited" | |
| docker compose logs server | |
| exit 1 | |
| fi | |
| if [ $count -gt 300 ]; then | |
| echo "Failed to start server after 5 minutes" | |
| docker compose logs server | |
| exit 1 | |
| fi | |
| echo "Still waiting for server... (${count}/300s)" | |
| done | |
| working-directory: ./packages/twenty-docker/ | |
| test-app-dev: | |
| needs: changed-files-check | |
| if: needs.changed-files-check.outputs.any_changed == 'true' | |
| timeout-minutes: 30 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| # Pull base images through Google's Docker Hub mirror — avoids Docker Hub | |
| # rate limits and needs no credentials (this repo is public). | |
| - name: Configure Docker Hub mirror | |
| run: | | |
| echo '{"registry-mirrors":["https://mirror.gcr.io"]}' | sudo tee /etc/docker/daemon.json | |
| sudo systemctl restart docker | |
| - name: Create frontend placeholder | |
| run: | | |
| mkdir -p packages/twenty-front/build | |
| echo '<html><body>CI placeholder</body></html>' > packages/twenty-front/build/index.html | |
| - name: Build app-dev image | |
| run: | | |
| docker build \ | |
| --target twenty-app-dev \ | |
| -f packages/twenty-docker/twenty/Dockerfile \ | |
| -t twenty-app-dev-ci \ | |
| . | |
| - name: Start container | |
| run: | | |
| docker run -d --name twenty-app-dev \ | |
| -p 2020:2020 \ | |
| twenty-app-dev-ci | |
| docker logs twenty-app-dev -f & | |
| - name: Wait for server health | |
| run: | | |
| echo "Waiting for twenty-app-dev to become healthy..." | |
| count=0 | |
| while true; do | |
| status=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:2020/healthz 2>/dev/null || echo "000") | |
| if [ "$status" = "200" ]; then | |
| echo "Server is healthy!" | |
| curl -s http://localhost:2020/healthz | |
| break | |
| fi | |
| container_status=$(docker inspect --format='{{.State.Status}}' twenty-app-dev 2>/dev/null || echo "unknown") | |
| if [ "$container_status" = "exited" ]; then | |
| echo "Container exited unexpectedly" | |
| docker logs twenty-app-dev | |
| exit 1 | |
| fi | |
| count=$((count+1)) | |
| if [ $count -gt 300 ]; then | |
| echo "Server did not become healthy within 5 minutes" | |
| docker logs twenty-app-dev | |
| exit 1 | |
| fi | |
| echo "Still waiting... (${count}/300s) [HTTP ${status}]" | |
| sleep 1 | |
| done | |
| ci-test-docker-status-check: | |
| if: always() && !cancelled() | |
| timeout-minutes: 5 | |
| runs-on: ubuntu-latest | |
| needs: [changed-files-check, test-compose, test-app-dev] | |
| steps: | |
| - name: Fail job if any needs failed | |
| if: contains(needs.*.result, 'failure') | |
| run: exit 1 | |