171 lines
6.0 KiB
YAML
171 lines
6.0 KiB
YAML
name: release
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*' # v1.2.3, v1.2.3-rc.1, etc.
|
|
|
|
jobs:
|
|
publish-image:
|
|
name: Build & Publish Image
|
|
runs-on: [self-hosted, linux, x64, docker]
|
|
container:
|
|
image: ghcr.io/catthehacker/ubuntu:act-latest
|
|
options: >-
|
|
--privileged
|
|
env:
|
|
REGISTRY: ${{ secrets.REGISTRY_HOST }}
|
|
OWNER_REPO: ${{ github.repository }}
|
|
DOCKERFILE: JSMR.Api/Dockerfile
|
|
CONTEXT: .
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Compute image name + tag + prerelease flag
|
|
id: meta
|
|
shell: bash
|
|
run: |
|
|
IMAGE_LC="$(echo "${REGISTRY}/${OWNER_REPO}" | tr '[:upper:]' '[:lower:]')"
|
|
echo "image=${IMAGE_LC}" >> "$GITHUB_OUTPUT"
|
|
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
if [[ "${GITHUB_REF_NAME}" == *"-"* ]]; then
|
|
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Docker login
|
|
run: |
|
|
echo "${{ secrets.REGISTRY_PASSWORD }}" \
|
|
| docker login "${{ env.REGISTRY }}" \
|
|
-u "${{ secrets.REGISTRY_USER }}" \
|
|
--password-stdin
|
|
|
|
- name: Enable BuildKit
|
|
run: echo "DOCKER_BUILDKIT=1" >> $GITHUB_ENV
|
|
|
|
- name: Build (from your API Dockerfile)
|
|
run: |
|
|
docker build \
|
|
-f "$DOCKERFILE" \
|
|
-t "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" \
|
|
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}" \
|
|
--label "org.opencontainers.image.version=${{ steps.meta.outputs.tag }}" \
|
|
"$CONTEXT"
|
|
|
|
- name: Push (tagged)
|
|
run: docker push "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}"
|
|
|
|
- name: Also tag/push :latest for stable tags only
|
|
if: ${{ steps.meta.outputs.is_prerelease == 'false' }}
|
|
run: |
|
|
docker tag "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" "${{ steps.meta.outputs.image }}:latest"
|
|
docker push "${{ steps.meta.outputs.image }}:latest"
|
|
|
|
# Optional: export a tiny text artifact with the image refs (handy for debugging)
|
|
- name: Emit image refs
|
|
run: |
|
|
echo "${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.tag }}" > image.txt
|
|
if [ "${{ steps.meta.outputs.is_prerelease }}" = "false" ]; then
|
|
echo "${{ steps.meta.outputs.image }}:latest" >> image.txt
|
|
fi
|
|
|
|
create-gitea-release:
|
|
name: Create Gitea Release
|
|
needs: publish-image
|
|
runs-on: [self-hosted, linux, x64, docker]
|
|
container:
|
|
image: ghcr.io/catthehacker/ubuntu:act-latest
|
|
options: >-
|
|
--privileged
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install jq (for safe JSON quoting)
|
|
run: |
|
|
apt-get update -y
|
|
apt-get install -y jq curl
|
|
|
|
- name: Prepare release notes
|
|
id: notes
|
|
env:
|
|
REGISTRY: ${{ secrets.REGISTRY_HOST }}
|
|
REPO: ${{ github.repository }}
|
|
shell: bash
|
|
run: |
|
|
TAG="${GITHUB_REF_NAME}"
|
|
IMG="${REGISTRY}/${REPO}:${TAG}"
|
|
cat > REL_NOTES.md <<EOF
|
|
## ${TAG}
|
|
|
|
**Images**
|
|
- \`${IMG}\`
|
|
EOF
|
|
# Add :latest mention only for stable tags
|
|
if [[ "$TAG" != *"-"* ]]; then
|
|
echo "- \`${REGISTRY}/${REPO}:latest\`" >> REL_NOTES.md
|
|
fi
|
|
|
|
- name: Create or Update Release via Gitea API
|
|
env:
|
|
GITEA_BASE: ${{ secrets.GITEA_BASE_URL }}
|
|
TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
shell: bash
|
|
run: |
|
|
TAG="${GITHUB_REF_NAME}"
|
|
BODY="$(cat REL_NOTES.md)"
|
|
IS_PRERELEASE=false
|
|
[[ "$TAG" == *"-"* ]] && IS_PRERELEASE=true
|
|
|
|
# Try to get existing release by tag
|
|
set +e
|
|
EXISTING=$(curl -s -H "Authorization: token ${TOKEN}" "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases/tags/${TAG}")
|
|
STATUS=$?
|
|
set -e
|
|
|
|
if echo "$EXISTING" | jq -e .id >/dev/null 2>&1; then
|
|
REL_ID=$(echo "$EXISTING" | jq -r .id)
|
|
# Update
|
|
curl -sS -X PATCH "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases/${REL_ID}" \
|
|
-H "Authorization: token ${TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$(jq -n --arg t "$TAG" --arg b "$BODY" --argjson pre $IS_PRERELEASE '{name:$t, body:$b, prerelease:$pre}')" >/dev/null
|
|
else
|
|
# Create
|
|
curl -sS -X POST "${GITEA_BASE}/api/v1/repos/${{ github.repository }}/releases" \
|
|
-H "Authorization: token ${TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$(jq -n --arg t "$TAG" --arg b "$BODY" --argjson pre $IS_PRERELEASE '{tag_name:$t, name:$t, body:$b, draft:false, prerelease:$pre}')" >/dev/null
|
|
fi
|
|
|
|
deploy-api:
|
|
name: Deploy API (Production)
|
|
needs: publish-image
|
|
runs-on: [self-hosted, linux, x64, docker] # your Synology runner
|
|
environment: production # optional: add env protection rules in Gitea
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Docker login (pull private image)
|
|
run: |
|
|
echo "${{ secrets.REGISTRY_PASSWORD }}" \
|
|
| docker login "${{ secrets.REGISTRY_HOST }}" \
|
|
-u "${{ secrets.REGISTRY_USER }}" \
|
|
--password-stdin
|
|
|
|
- name: Render env file for compose
|
|
run: |
|
|
mkdir -p deploy
|
|
cat > deploy/.env <<EOF
|
|
REGISTRY=${{ secrets.REGISTRY_HOST }}
|
|
IMAGE_NS=${{ github.repository }}
|
|
TAG=${GITHUB_REF_NAME}
|
|
DB_CONN=${{ secrets.DB_CONNECTION_STRING }}
|
|
ALLOWED_ORIGINS=${{ secrets.ALLOWED_ORIGINS }}
|
|
TZ=America/Detroit
|
|
EOF
|
|
|
|
- name: Deploy (pull & up -d)
|
|
run: |
|
|
docker compose -f deploy/docker-compose.api.yml --env-file deploy/.env pull
|
|
docker compose -f deploy/docker-compose.api.yml --env-file deploy/.env up -d
|