Skip to content
This repository was archived by the owner on Apr 21, 2026. It is now read-only.

fix: Revert broken params in remaining controllers/models, fix seed IDs #143

fix: Revert broken params in remaining controllers/models, fix seed IDs

fix: Revert broken params in remaining controllers/models, fix seed IDs #143

Workflow file for this run

name: Deploy to Docker Swarm
on:
push:
branches:
- main
env:
IMAGE_NAME: ghcr.io/wheels-dev/wheels-dev
REGISTRY: ghcr.io
jobs:
build:
name: Build & Push Image
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Resolve base image digest for reproducible builds
run: |
docker pull ortussolutions/commandbox:lucee6
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ortussolutions/commandbox:lucee6)
echo "COMMANDBOX_DIGEST=${DIGEST}" >> "$GITHUB_ENV"
echo "Pinned base image: ${DIGEST}"
- name: Copy swarm Dockerfile to root
run: |
cp ./deploy/swarm/dockerfile ./
- name: Install CommandBox
uses: Ortus-Solutions/setup-commandbox@v2.0.1
with:
forgeboxAPIKey: ${{ secrets.FORGEBOX_API_KEY }}
- name: Install wheels-cli and dependencies
run: |
box install wheels-cli
box install
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./dockerfile
push: true
build-args: |
COMMANDBOX_IMAGE=${{ env.COMMANDBOX_DIGEST }}
tags: |
${{ env.IMAGE_NAME }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy:
name: Deploy to Swarm
runs-on: [self-hosted, Linux, swarm]
needs: build
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to GHCR
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_ACTOR: ${{ github.actor }}
run: |
echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GH_ACTOR" --password-stdin
- name: Set task history limit
run: docker swarm update --task-history-limit 2
- name: Resolve compose file with secrets
env:
IMAGE_TAG: ${{ github.sha }}
RELOAD_PASSWORD: ${{ secrets.RELOAD_PASSWORD }}
CFCONFIG_ADMIN_PASSWORD: ${{ secrets.CFCONFIG_ADMIN_PASSWORD }}
WHEELSDEV_HOST: ${{ secrets.WHEELSDEV_HOST }}
WHEELSDEV_PORT: ${{ secrets.WHEELSDEV_PORT }}
WHEELSDEV_DATABASENAME: ${{ secrets.WHEELSDEV_DATABASENAME }}
WHEELSDEV_USERNAME: ${{ secrets.WHEELSDEV_USERNAME }}
WHEELSDEV_PASSWORD: ${{ secrets.WHEELSDEV_PASSWORD }}
SMTP_USERNAME: ${{ secrets.SMTP_USERNAME }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
WHEELS_ID_SALT: ${{ secrets.WHEELS_ID_SALT }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
run: |
envsubst '$IMAGE_TAG $RELOAD_PASSWORD $CFCONFIG_ADMIN_PASSWORD $WHEELSDEV_HOST $WHEELSDEV_PORT $WHEELSDEV_DATABASENAME $WHEELSDEV_USERNAME $WHEELSDEV_PASSWORD $SMTP_USERNAME $SMTP_PASSWORD $WHEELS_ID_SALT $SENTRY_DSN' \
< deploy/swarm/docker-compose.yml \
> /tmp/docker-compose-resolved.yml
- name: Deploy stack via Portainer API
env:
PORTAINER_URL: ${{ secrets.PORTAINER_URL }}
PORTAINER_API_KEY: ${{ secrets.PORTAINER_API_KEY }}
PORTAINER_ENDPOINT_ID: ${{ secrets.PORTAINER_ENDPOINT_ID }}
run: |
COMPOSE_CONTENT=$(cat /tmp/docker-compose-resolved.yml)
# Get the swarm ID from Portainer
SWARM_ID=$(curl -sf \
-H "X-API-Key: ${PORTAINER_API_KEY}" \
"${PORTAINER_URL}/api/endpoints/${PORTAINER_ENDPOINT_ID}/docker/swarm" \
| jq -r '.ID')
echo "Swarm ID: ${SWARM_ID}"
# Check if the stack already exists
STACK_INFO=$(curl -sf \
-H "X-API-Key: ${PORTAINER_API_KEY}" \
"${PORTAINER_URL}/api/stacks" \
| jq -r '.[] | select(.Name == "wheels-dev")')
if [ -n "$STACK_INFO" ]; then
STACK_ID=$(echo "$STACK_INFO" | jq -r '.Id')
echo "Updating existing stack (ID: ${STACK_ID})..."
HTTP_CODE=$(curl -s -o /tmp/portainer-response.json -w "%{http_code}" \
-X PUT \
-H "X-API-Key: ${PORTAINER_API_KEY}" \
-H "Content-Type: application/json" \
"${PORTAINER_URL}/api/stacks/${STACK_ID}?endpointId=${PORTAINER_ENDPOINT_ID}" \
-d "$(jq -n --arg content "$COMPOSE_CONTENT" '{
"stackFileContent": $content,
"prune": true
}')")
else
echo "Creating new stack..."
HTTP_CODE=$(curl -s -o /tmp/portainer-response.json -w "%{http_code}" \
-X POST \
-H "X-API-Key: ${PORTAINER_API_KEY}" \
-H "Content-Type: application/json" \
"${PORTAINER_URL}/api/stacks/create/swarm/string?endpointId=${PORTAINER_ENDPOINT_ID}" \
-d "$(jq -n --arg name "wheels-dev" --arg swarm "$SWARM_ID" --arg content "$COMPOSE_CONTENT" '{
"name": $name,
"swarmID": $swarm,
"stackFileContent": $content
}')")
fi
echo "Portainer API response code: ${HTTP_CODE}"
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Error response:"
cat /tmp/portainer-response.json
exit 1
fi
echo "Stack deployed successfully via Portainer"
- name: Update service to SHA-tagged image
env:
IMAGE_TAG: ${{ github.sha }}
run: |
for i in 1 2 3 4 5; do
docker service update \
--with-registry-auth \
--image "ghcr.io/wheels-dev/wheels-dev:${IMAGE_TAG}" \
--force \
wheels-dev_wheels-dev && break
echo "Attempt $i failed (update out of sequence), retrying in 15s..."
sleep 15
done
- name: Verify deployment
run: |
echo "Waiting for services to stabilize..."
sleep 30
docker service ls
echo ""
echo "Checking wheels-dev service replicas..."
docker service ps wheels-dev_wheels-dev --no-trunc