Bump bootsnap from 1.25.0 to 1.26.0 #5909
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| jobs: | |
| scan_ruby: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Scan for vulnerabilities with Brakeman | |
| continue-on-error: true | |
| run: bin/brakeman --no-pager -f sarif -o brakeman.sarif.json | |
| - name: Upload SARIF to GitHub Code Scanning | |
| uses: github/codeql-action/upload-sarif@v4.37.9 | |
| with: | |
| sarif_file: brakeman.sarif.json | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Lint code for consistent style | |
| run: bin/rubocop -f github | |
| frontend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Install libvips | |
| run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libvips42t64 | |
| - name: Set up Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install JavaScript dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Generate js_from_routes path helpers | |
| env: | |
| JS_FROM_ROUTES_FORCE: "true" | |
| run: bin/rake js_from_routes:generate | |
| - name: Run Svelte type checks | |
| run: bun run check:svelte | |
| - name: Run Svelte formatting checks | |
| run: bun run format:svelte:check | |
| - name: Run frontend lint checks | |
| run: bun run lint | |
| - name: Run Knip (unused files / deps / exports) | |
| run: bun run knip | |
| zeitwerk: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Install libvips | |
| run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libvips42t64 | |
| - name: Run Rails Zeitwerk check | |
| run: bin/rails zeitwerk:check | |
| docker_build: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| dockerfile: ${{ fromJSON(github.event_name == 'pull_request' && '["Dockerfile", "Dockerfile.dev"]' || '["Dockerfile.dev"]') }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Blacksmith Builder | |
| uses: useblacksmith/setup-docker-builder@v2 | |
| with: | |
| cache-key: hackatime/v3/${{ matrix.dockerfile }} | |
| nofallback: true | |
| - name: Build ${{ matrix.dockerfile }} | |
| uses: useblacksmith/build-push-action@v2 | |
| with: | |
| context: "{{defaultContext}}" | |
| file: ${{ matrix.dockerfile }} | |
| load: false | |
| push: false | |
| publish_image: | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Blacksmith Builder | |
| uses: useblacksmith/setup-docker-builder@v2 | |
| with: | |
| cache-key: hackatime/v3/Dockerfile | |
| nofallback: true | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and publish production image | |
| uses: useblacksmith/build-push-action@v2 | |
| with: | |
| build-args: SOURCE_COMMIT=${{ github.sha }} | |
| context: "{{defaultContext}}" | |
| file: Dockerfile | |
| labels: org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} | |
| load: false | |
| push: true | |
| tags: ghcr.io/${{ github.repository }}:${{ github.sha }} | |
| test: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| ports: | |
| - 5432:5432 | |
| options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: app_test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Install libvips | |
| run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libvips42t64 | |
| - name: Run tests | |
| env: | |
| RAILS_ENV: test | |
| TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/app_test | |
| PGHOST: localhost | |
| PGUSER: postgres | |
| PGPASSWORD: postgres | |
| run: | | |
| bin/rails db:create RAILS_ENV=test | |
| bin/rails db:schema:load RAILS_ENV=test | |
| bin/rails test | |
| - name: Ensure Swagger docs are up to date | |
| env: | |
| RAILS_ENV: test | |
| TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/app_test | |
| PGHOST: localhost | |
| PGUSER: postgres | |
| PGPASSWORD: postgres | |
| run: | | |
| bin/rails rswag:specs:swaggerize | |
| git diff --exit-code swagger/ | |
| test_system: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| ports: | |
| - 5432:5432 | |
| options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: app_test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Set up Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: .ruby-version | |
| bundler-cache: true | |
| - name: Install libvips | |
| run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libvips42t64 | |
| - name: Set up Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Setup Chrome | |
| id: setup-chrome | |
| uses: browser-actions/setup-chrome@latest | |
| with: | |
| install-chromedriver: true | |
| - name: Install JavaScript dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Generate js_from_routes path helpers | |
| env: | |
| JS_FROM_ROUTES_FORCE: "true" | |
| run: bin/rake js_from_routes:generate | |
| - name: Pre-build Vite assets for test | |
| run: bin/vite build | |
| env: | |
| RAILS_ENV: test | |
| - name: Run system tests | |
| env: | |
| RAILS_ENV: test | |
| TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/app_test | |
| PGHOST: localhost | |
| PGUSER: postgres | |
| PGPASSWORD: postgres | |
| CHROME_BIN: ${{ steps.setup-chrome.outputs.chrome-path }} | |
| CHROMEDRIVER_BIN: ${{ steps.setup-chrome.outputs.chromedriver-path }} | |
| run: | | |
| bin/rails db:create RAILS_ENV=test | |
| bin/rails db:schema:load RAILS_ENV=test | |
| bin/rails test:system | |
| - name: Keep screenshots from failed system tests | |
| uses: actions/upload-artifact@v7 | |
| if: failure() | |
| with: | |
| name: screenshots | |
| path: ${{ github.workspace }}/tmp/screenshots | |
| if-no-files-found: ignore | |
| deploy: | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| needs: [scan_ruby, lint, frontend, zeitwerk, publish_image, test, test_system] | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: production-deploy | |
| cancel-in-progress: false | |
| environment: production | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Deploy immutable image through Coolify | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| COOLIFY_URL: ${{ secrets.COOLIFY_URL }} | |
| COOLIFY_API_TOKEN: ${{ secrets.COOLIFY_API_TOKEN }} | |
| COOLIFY_WEB_APPLICATION_UUID: ${{ secrets.COOLIFY_WEB_APPLICATION_UUID }} | |
| COOLIFY_WORKER_APPLICATION_UUID: ${{ secrets.COOLIFY_WORKER_APPLICATION_UUID }} | |
| IMAGE_NAME: ghcr.io/${{ github.repository }} | |
| IMAGE_TAG: ${{ github.sha }} | |
| run: | | |
| set -Eeuo pipefail | |
| : "${COOLIFY_URL:?Set the COOLIFY_URL production environment secret}" | |
| : "${COOLIFY_API_TOKEN:?Set the COOLIFY_API_TOKEN production environment secret}" | |
| : "${COOLIFY_WEB_APPLICATION_UUID:?Set the COOLIFY_WEB_APPLICATION_UUID production environment secret}" | |
| : "${COOLIFY_WORKER_APPLICATION_UUID:?Set the COOLIFY_WORKER_APPLICATION_UUID production environment secret}" | |
| if [ "$COOLIFY_WEB_APPLICATION_UUID" = "$COOLIFY_WORKER_APPLICATION_UUID" ]; then | |
| echo "::error::Web and worker must be separate Coolify applications." | |
| exit 1 | |
| fi | |
| coolify_url="${COOLIFY_URL%/}" | |
| api_url="${coolify_url}/api/v1" | |
| authorization="Authorization: Bearer ${COOLIFY_API_TOKEN}" | |
| ensure_current_main() { | |
| latest_main_sha="$(curl --fail-with-body --silent --show-error \ | |
| --connect-timeout 10 --max-time 60 \ | |
| --retry 3 --retry-all-errors \ | |
| --header "Authorization: Bearer ${GH_TOKEN}" \ | |
| --header 'Accept: application/vnd.github+json' \ | |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/commits/main" | jq -er '.sha')" | |
| if [ "$latest_main_sha" != "$IMAGE_TAG" ]; then | |
| echo "::notice::Skipping stale deployment of ${IMAGE_TAG}; main is ${latest_main_sha}." | |
| exit 0 | |
| fi | |
| } | |
| ensure_current_main | |
| for application_uuid in "$COOLIFY_WEB_APPLICATION_UUID" "$COOLIFY_WORKER_APPLICATION_UUID"; do | |
| application="$(curl --fail-with-body --silent --show-error \ | |
| --connect-timeout 10 --max-time 60 \ | |
| --retry 3 --retry-all-errors \ | |
| --header "$authorization" \ | |
| "${api_url}/applications/${application_uuid}")" | |
| if [ "$(jq -r '.build_pack' <<<"$application")" != "dockerimage" ]; then | |
| echo "::error::${application_uuid} must identify a Docker Image application." | |
| exit 1 | |
| fi | |
| done | |
| ensure_current_main | |
| update_payload="$(jq -cn \ | |
| --arg image "$IMAGE_NAME" \ | |
| --arg tag "$IMAGE_TAG" \ | |
| '{docker_registry_image_name: $image, docker_registry_image_tag: $tag}')" | |
| for application_uuid in "$COOLIFY_WEB_APPLICATION_UUID" "$COOLIFY_WORKER_APPLICATION_UUID"; do | |
| curl --fail-with-body --silent --show-error \ | |
| --connect-timeout 10 --max-time 60 \ | |
| --retry 3 --retry-all-errors \ | |
| --request PATCH \ | |
| --header "$authorization" \ | |
| --header 'Content-Type: application/json' \ | |
| --data "$update_payload" \ | |
| --output /dev/null \ | |
| "${api_url}/applications/${application_uuid}" | |
| done | |
| ensure_current_main | |
| application_uuids="${COOLIFY_WEB_APPLICATION_UUID},${COOLIFY_WORKER_APPLICATION_UUID}" | |
| deploy_payload="$(jq -cn --arg uuid "$application_uuids" '{uuid: $uuid}')" | |
| deploy_response="$(curl --fail-with-body --silent --show-error \ | |
| --connect-timeout 10 --max-time 60 \ | |
| --request POST \ | |
| --header "$authorization" \ | |
| --header 'Content-Type: application/json' \ | |
| --data "$deploy_payload" \ | |
| "${api_url}/deploy")" | |
| deployment_rows="$(jq -er \ | |
| --arg web "$COOLIFY_WEB_APPLICATION_UUID" \ | |
| --arg worker "$COOLIFY_WORKER_APPLICATION_UUID" ' | |
| [.deployments[] | | |
| select(.resource_uuid == $web or .resource_uuid == $worker) | | |
| select(.deployment_uuid | type == "string" and length > 0)] as $deployments | | |
| if ($deployments | map(select(.resource_uuid == $web)) | length) == 1 and | |
| ($deployments | map(select(.resource_uuid == $worker)) | length) == 1 | |
| then $deployments[] | [.resource_uuid, .deployment_uuid] | @tsv | |
| else error("Coolify did not queue exactly one web and one worker deployment") | |
| end | |
| ' <<<"$deploy_response")" | |
| deadline=$((SECONDS + 900)) | |
| while IFS=$'\t' read -r application_uuid deployment_uuid; do | |
| echo "Coolify deployment queued for ${application_uuid}: ${deployment_uuid}" | |
| status="" | |
| while :; do | |
| deployment="$(curl --fail-with-body --silent --show-error \ | |
| --connect-timeout 10 --max-time 60 \ | |
| --retry 3 --retry-all-errors \ | |
| --header "$authorization" \ | |
| "${api_url}/deployments/${deployment_uuid}")" | |
| status="$(jq -er '.status' <<<"$deployment")" | |
| echo "Coolify deployment ${deployment_uuid} status: ${status}" | |
| case "$status" in | |
| queued|in_progress) | |
| if (( SECONDS >= deadline )); then | |
| echo "::error::Coolify deployment ${deployment_uuid} did not finish within 15 minutes." | |
| exit 1 | |
| fi | |
| sleep 5 | |
| ;; | |
| finished) | |
| break | |
| ;; | |
| failed|cancelled-by-user) | |
| echo "::error::Coolify deployment ${deployment_uuid} ended with status ${status}." | |
| exit 1 | |
| ;; | |
| *) | |
| echo "::error::Unknown Coolify deployment status: ${status}" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| done <<<"$deployment_rows" |