Skip to content

fix railway deploy

fix railway deploy #52

Workflow file for this run

name: Actions Image
on:
push:
branches:
- talos
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up SSH agent for @automaton/client deploy key
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.TALOS_DEPLOY_KEY }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare image metadata
id: prep
run: |
IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/arm-actions"
IMAGE_NAME="$(echo "${IMAGE_NAME}" | tr '[:upper:]' '[:lower:]')"
echo "image_name=${IMAGE_NAME}" >> "${GITHUB_OUTPUT}"
- name: Build and push image
uses: docker/build-push-action@v5
with:
context: .
file: ./dockerfile-actions
push: true
ssh: default
tags: |
${{ steps.prep.outputs.image_name }}:latest
${{ steps.prep.outputs.image_name }}:${{ github.sha }}
# `railway redeploy` re-runs the last deployment using the digest
# Railway already had — it does NOT pull a fresh `:latest` from GHCR,
# which is why pushed images sometimes never went live. Instead, pin
# the service to the SHA-tagged image we just pushed; Railway treats
# a source-image change as a deploy trigger and pulls + runs it.
- name: Deploy pinned image to Railway
if: success() && env.RAILWAY_TOKEN != ''
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
RAILWAY_SERVICE_ID: ${{ secrets.RAILWAY_SERVICE_ID }}
RAILWAY_ENVIRONMENT_ID: ${{ secrets.RAILWAY_ENVIRONMENT_ID }}
IMAGE: ${{ steps.prep.outputs.image_name }}:${{ github.sha }}
run: |
set -euo pipefail
if [ -z "${RAILWAY_ENVIRONMENT_ID:-}" ]; then
echo "::error::RAILWAY_ENVIRONMENT_ID secret is required for image-pinned deploys." >&2
echo "::error::Find it in Railway: open the service, the URL contains /environment/<id>." >&2
echo "::error::Add it under Settings → Secrets and variables → Actions." >&2
exit 1
fi
payload=$(jq -n \
--arg serviceId "$RAILWAY_SERVICE_ID" \
--arg environmentId "$RAILWAY_ENVIRONMENT_ID" \
--arg image "$IMAGE" \
'{
query: "mutation($serviceId: String!, $environmentId: String!, $input: ServiceInstanceUpdateInput!) { serviceInstanceUpdate(serviceId: $serviceId, environmentId: $environmentId, input: $input) }",
variables: {
serviceId: $serviceId,
environmentId: $environmentId,
input: { source: { image: $image } }
}
}')
# Project tokens authenticate via `Project-Access-Token`, not
# `Authorization: Bearer` (which is for account / workspace
# tokens). See https://docs.railway.com/integrations/api.
response=$(curl -fsSL -X POST https://backboard.railway.com/graphql/v2 \
-H "Project-Access-Token: $RAILWAY_TOKEN" \
-H "Content-Type: application/json" \
-d "$payload")
echo "$response"
if echo "$response" | jq -e '.errors' > /dev/null; then
echo "::error::Railway API returned errors — see response above" >&2
exit 1
fi
echo "✓ Pinned service image to $IMAGE."
- name: Trigger Railway redeploy
if: success() && env.RAILWAY_TOKEN != ''
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
RAILWAY_SERVICE_ID: ${{ secrets.RAILWAY_SERVICE_ID }}
run: |
# Fires the actual deploy. The previous step changed the source
# to the SHA-tagged image but `serviceInstanceUpdate` alone does
# not trigger a deployment — Railway needs an explicit poke.
npm i -g @railway/cli
railway link --project "$RAILWAY_PROJECT_ID"
railway service "$RAILWAY_SERVICE_ID"
railway deploy --yes