Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Docker Publish

on:
workflow_call:
inputs:
is_prerelease:
description: "Whether the source release is a prerelease"
type: boolean
required: false
default: false
version:
description: "Semver version to tag (e.g. 1.2.3)"
type: string
required: true

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/thaddeusjiang/save_it
tags: |
type=raw,value=latest,enable=${{ !inputs.is_prerelease }}
type=raw,value=${{ inputs.version }},enable=${{ inputs.version != '' }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Verify published manifests
env:
TAGS: ${{ steps.meta.outputs.tags }}
run: |
printf '%s\n' "$TAGS" | while IFS= read -r tag; do
[ -n "$tag" ] || continue
docker buildx imagetools inspect "$tag"
done
74 changes: 74 additions & 0 deletions .github/workflows/release-manual.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Manually create and publish a GitHub pre-release from a branch and tag.
name: Release (manual)

on:
workflow_dispatch:
inputs:
branch:
description: "Branch to release from"
required: true
type: string
tag:
description: "Release tag to create (for example: v0.4.1)"
required: true
type: string

permissions:
contents: write

concurrency:
group: release-manual-${{ inputs.tag }}
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.branch }}

- name: Ensure GitHub CLI
run: gh --version

- name: Validate branch and tag
env:
INPUT_BRANCH: ${{ inputs.branch }}
INPUT_TAG: ${{ inputs.tag }}
run: |
git fetch origin "$INPUT_BRANCH"

if ! printf '%s' "$INPUT_TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$'; then
echo "Tag must look like v0.4.1 or v0.4.1-rc.1: $INPUT_TAG"
exit 1
fi

if gh release view "$INPUT_TAG" >/dev/null 2>&1; then
echo "Release already exists for tag $INPUT_TAG"
exit 1
fi

- name: Create published GitHub pre-release
env:
GH_TOKEN: ${{ github.token }}
INPUT_BRANCH: ${{ inputs.branch }}
INPUT_TAG: ${{ inputs.tag }}
run: |
version="${INPUT_TAG#v}"

awk -v version="$version" '
$0 ~ "^## \\[" version "\\]" { next_section=1; next }
next_section && /^## \[/ { exit }
next_section { print }
' CHANGELOG.md > release-notes.md

if [ ! -s release-notes.md ]; then
printf 'Release %s\n' "$INPUT_TAG" > release-notes.md
fi

gh release create "$INPUT_TAG" \
--target "$INPUT_BRANCH" \
--title "$INPUT_TAG" \
--notes-file release-notes.md \
--prerelease
47 changes: 47 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Publish Docker image when a GitHub release is published.
name: Release

on:
release:
types:
- published

permissions:
contents: read
packages: write

concurrency:
group: release-${{ github.event.release.tag_name }}
cancel-in-progress: false

jobs:
prepare:
runs-on: ubuntu-latest
outputs:
is_prerelease: ${{ steps.prepare.outputs.is_prerelease }}
version: ${{ steps.prepare.outputs.version }}
steps:
- name: Derive image version from release tag
id: prepare
env:
IS_PRERELEASE: ${{ github.event.release.prerelease }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
version="${RELEASE_TAG#v}"
if [ -z "$version" ]; then
echo "Release tag is empty"
exit 1
fi
echo "is_prerelease=${IS_PRERELEASE}" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"

docker:
needs: prepare
uses: ./.github/workflows/docker-publish.yml
with:
is_prerelease: ${{ needs.prepare.outputs.is_prerelease == 'true' }}
version: ${{ needs.prepare.outputs.version }}
permissions:
contents: read
packages: write
secrets: inherit
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Elixir
uses: erlef/setup-beam@v1
Expand Down
6 changes: 6 additions & 0 deletions docs/deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ SENTRY_DSN=
GOOGLE_OAUTH_CLIENT_ID=
GOOGLE_OAUTH_CLIENT_SECRET=
```

## Docker Image

- Published image: `ghcr.io/thaddeusjiang/save_it`
- Zeabur template image tag: `latest`
- Local build check: `mise run confirm-docker-build`
6 changes: 6 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ run = [
"npx zeabur template update -c FTAONK -f others/zeabur/template.yaml",
"echo '✅ https://zeabur.com/templates/FTAONK'",
]

[tasks.confirm-docker-build]
description = "Build the production image locally"
run = [
"docker build -t save_it:local .",
]
7 changes: 2 additions & 5 deletions others/zeabur/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ spec:
services:
- name: save_it_bot
icon: https://raw.githubusercontent.com/ThaddeusJiang/save_it/refs/heads/main/docs/assets/savt_it_bot_logo.jpg
template: GIT
template: PREBUILT_V2
spec:
source:
source: GITHUB
repo: 831394769
branch: main
rootDirectory: /
image: ghcr.io/thaddeusjiang/save_it:latest
volumes:
- id: bot-data
dir: /data
Expand Down
Loading