Skip to content

Scheduled Release

Scheduled Release #3

name: Nightly Release
on:
workflow_dispatch:
schedule:
# GitHub Actions cron uses UTC.
# 19:00 UTC == 03:00 Asia/Shanghai on the next day.
- cron: "0 19 * * *"
permissions:
contents: write
jobs:
precheck:
name: Precheck nightly commit
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.check.outputs.should_skip }}
steps:
- name: Check latest nightly release commit
id: check
uses: actions/github-script@v7
with:
script: |
const currentSha = context.sha;
const { owner, repo } = context.repo;
const releases = await github.paginate(github.rest.repos.listReleases, {
owner,
repo,
per_page: 100
});
const nightly = releases.find((release) =>
release.prerelease &&
typeof release.tag_name === "string" &&
release.tag_name.startsWith("nightly-")
);
if (!nightly) {
core.info("no previous nightly release found");
core.setOutput("should_skip", "false");
return;
}
const body = nightly.body || "";
const match = body.match(/Commit:\s*([0-9a-f]{40})/i);
if (!match) {
core.info("previous nightly release has no commit marker");
core.setOutput("should_skip", "false");
return;
}
const previousSha = match[1].toLowerCase();
core.info(`current sha: ${currentSha}`);
core.info(`previous nightly sha: ${previousSha}`);
core.setOutput("should_skip", previousSha === currentSha.toLowerCase() ? "true" : "false");
build:
name: Build ${{ matrix.goos }}-${{ matrix.goarch }}
runs-on: ubuntu-latest
needs: precheck
if: needs.precheck.outputs.should_skip != 'true'
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_prefix: linux-amd64
binary_name: web-model
- goos: darwin
goarch: amd64
asset_prefix: macos-amd64
binary_name: web-model
- goos: windows
goarch: amd64
asset_prefix: windows-amd64
binary_name: web-model.exe
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build package
shell: bash
run: |
set -euo pipefail
stage_dir="dist/${{ matrix.asset_prefix }}"
mkdir -p "${stage_dir}"
CGO_ENABLED=0 GOOS="${{ matrix.goos }}" GOARCH="${{ matrix.goarch }}" \
go build -trimpath -ldflags="-s -w" \
-o "${stage_dir}/${{ matrix.binary_name }}" \
./cmd/web-model
cp -R extension "${stage_dir}/extension"
tar -C dist -czf "dist/${{ matrix.asset_prefix }}-all.tgz" "${{ matrix.asset_prefix }}"
- name: Upload packaged artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_prefix }}-all
path: dist/${{ matrix.asset_prefix }}-all.tgz
if-no-files-found: error
release:
name: Publish nightly release
runs-on: ubuntu-latest
needs:
- precheck
- build
if: needs.precheck.outputs.should_skip != 'true'
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: release-assets
- name: Compute release metadata
id: meta
shell: bash
run: |
set -euo pipefail
nightly_date="$(TZ=Asia/Shanghai date +%Y-%m-%d)"
nightly_tag="$(TZ=Asia/Shanghai date +nightly-%Y%m%d)"
echo "date=${nightly_date}" >> "$GITHUB_OUTPUT"
echo "tag=${nightly_tag}" >> "$GITHUB_OUTPUT"
- name: Verify packaged assets
shell: bash
run: |
set -euo pipefail
find release-assets -type f -name '*-all.tgz' | sort
count="$(find release-assets -type f -name '*-all.tgz' | wc -l | tr -d ' ')"
if [ "$count" -eq 0 ]; then
echo "no packaged assets found" >&2
exit 1
fi
- name: Publish prerelease
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.meta.outputs.tag }}
name: Nightly ${{ steps.meta.outputs.date }}
body: |
Automated nightly prerelease build.
Commit: ${{ github.sha }}
prerelease: true
make_latest: false
files: |
release-assets/**/*-all.tgz