Skip to content

Bump bootsnap from 1.25.0 to 1.26.0 #5909

Bump bootsnap from 1.25.0 to 1.26.0

Bump bootsnap from 1.25.0 to 1.26.0 #5909

Workflow file for this run

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"