feat(ci): automate Linux release builds and Gitea releases
Release / release (push) Successful in 13m50s
Release / release (push) Successful in 13m50s
Local flow is now ./release 1.6.7 (or make release VERSION=1.6.7): bump wails.json productVersion, commit the bump, generate git-cliff notes into an annotated plain-version tag, and push commit plus tag. The tag push fires the new Gitea Actions workflow. - cliff.toml: git-cliff groups matching Bookhoard, tag_pattern for plain versions so --latest scopes correctly. - Makefile release target: strict plain-semver validation, dirty-tree and existing-tag guards, python3 wails.json bump committed as chore(release), throwaway-tag notes generation, push of main + tag. - release: wrapper normalizing v/AniTrack- prefixes to plain versions. - .gitea/workflows/release.yml: version guard (wails.json vs tag, base-match for -suffix pre-releases), Go 1.25 / Node 20 / Wails v2.15.0 + webkit2_41 system deps, environment.go from Actions secrets, make build, AniTrack-<version>.tar.gz packaged from build/ (bin, icon, desktop, install script, README), idempotent Release create/update named AniTrack-<version> with archive attached via REGISTRY_TOKEN PAT.
This commit is contained in:
@@ -0,0 +1,251 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
# Overrides the default run name (the tagged commit's message) so the Actions
|
||||||
|
# runs list shows "Release 1.6.7" instead.
|
||||||
|
run-name: "Release ${{ gitea.event.inputs.tag || gitea.ref_name }}"
|
||||||
|
|
||||||
|
# Builds the Wails Linux binary via `make build`, packages
|
||||||
|
# AniTrack-<version>.tar.gz from build/, and creates/updates a Gitea Release
|
||||||
|
# named AniTrack-<version> with the archive attached. Triggered by a plain
|
||||||
|
# version tag push (1.6.7), or manually via workflow_dispatch with a tag for
|
||||||
|
# re-runs and secrets tests. Pushing to main does nothing, so
|
||||||
|
# work-in-progress commits never ship.
|
||||||
|
#
|
||||||
|
# Local flow: `./release 1.6.7` (or `make release VERSION=1.6.7`) bumps
|
||||||
|
# wails.json, commits the bump, creates an annotated tag carrying the
|
||||||
|
# git-cliff notes, and pushes commit + tag. This workflow verifies
|
||||||
|
# wails.json matches the tag before building.
|
||||||
|
#
|
||||||
|
# Secrets test (verifies environment.go wiring without shipping): tag the
|
||||||
|
# current bumped commit with a suffix and push, e.g.
|
||||||
|
# git tag 1.6.7-rc1 && git push origin 1.6.7-rc1
|
||||||
|
# Tags containing '-' are published as pre-releases; delete the test
|
||||||
|
# Release/tag afterwards.
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '[0-9]*.[0-9]*.[0-9]*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Tag to release (e.g. 1.6.7)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
env:
|
||||||
|
# Resolve the target tag for both triggers: explicit input on manual
|
||||||
|
# dispatch, otherwise the pushed tag ref.
|
||||||
|
TAG: ${{ gitea.event.inputs.tag || gitea.ref_name }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
# Full history ensures the tag annotation (the release notes) is present.
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: ${{ gitea.event.inputs.tag || gitea.ref }}
|
||||||
|
|
||||||
|
- name: Guard wails.json matches tag
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
: "${TAG:?TAG is required}"
|
||||||
|
# Normalize "v1.6.7" / "AniTrack-1.6.7" to plain "1.6.7" (make release
|
||||||
|
# only ever creates plain tags; this tolerates manual typos).
|
||||||
|
NORM="${TAG#v}"
|
||||||
|
NORM="${NORM#AniTrack-}"
|
||||||
|
BASE="${NORM%%-*}"
|
||||||
|
WAILS_VER="$(python3 -c "import json; print(json.load(open('wails.json'))['info']['productVersion'])")"
|
||||||
|
if [ "${NORM}" = "${BASE}" ]; then
|
||||||
|
if [ "${WAILS_VER}" != "${NORM}" ]; then
|
||||||
|
echo "::error::wails.json productVersion (${WAILS_VER}) != tag (${NORM}). Bump via ./release ${NORM} first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Pre-release (e.g. 1.6.7-rc1): wails.json must match the base version.
|
||||||
|
if [ "${WAILS_VER}" != "${BASE}" ]; then
|
||||||
|
echo "::error::wails.json productVersion (${WAILS_VER}) != tag base (${BASE}). Bump via ./release ${BASE} first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "VERSION=${NORM}" >> "${GITHUB_ENV}"
|
||||||
|
echo "Version guard passed: wails.json=${WAILS_VER} tag=${NORM}"
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.25'
|
||||||
|
cache-dependency-path: go.sum
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Install Wails Linux build dependencies
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential pkg-config \
|
||||||
|
libgtk-3-dev libwebkit2gtk-4.1-dev \
|
||||||
|
jq
|
||||||
|
|
||||||
|
- name: Install Wails CLI
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
go install github.com/wailsapp/wails/v2/cmd/wails@v2.15.0
|
||||||
|
echo "${HOME}/go/bin" >> "${GITHUB_PATH}"
|
||||||
|
|
||||||
|
- name: Write environment.go from secrets
|
||||||
|
env:
|
||||||
|
ANILIST_SECRET_TOKEN: ${{ secrets.ANILIST_SECRET_TOKEN }}
|
||||||
|
ANILIST_APP_ID: ${{ secrets.ANILIST_APP_ID }}
|
||||||
|
ANILIST_APP_NAME: ${{ secrets.ANILIST_APP_NAME }}
|
||||||
|
ANILIST_CALLBACK_URI: ${{ secrets.ANILIST_CALLBACK_URI }}
|
||||||
|
SIMKL_CLIENT_ID: ${{ secrets.SIMKL_CLIENT_ID }}
|
||||||
|
SIMKL_CLIENT_SECRET: ${{ secrets.SIMKL_CLIENT_SECRET }}
|
||||||
|
SIMKL_CALLBACK_URI: ${{ secrets.SIMKL_CALLBACK_URI }}
|
||||||
|
MAL_CLIENT_ID: ${{ secrets.MAL_CLIENT_ID }}
|
||||||
|
MAL_CLIENT_SECRET: ${{ secrets.MAL_CLIENT_SECRET }}
|
||||||
|
MAL_CALLBACK_URI: ${{ secrets.MAL_CALLBACK_URI }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# All 10 fields come from Gitea Actions secrets (never committed).
|
||||||
|
# Values are masked in logs; do not echo them or run with set -x.
|
||||||
|
for v in ANILIST_SECRET_TOKEN ANILIST_APP_ID ANILIST_APP_NAME ANILIST_CALLBACK_URI SIMKL_CLIENT_ID SIMKL_CLIENT_SECRET SIMKL_CALLBACK_URI MAL_CLIENT_ID MAL_CLIENT_SECRET MAL_CALLBACK_URI; do
|
||||||
|
if [ -z "${!v:-}" ]; then
|
||||||
|
echo "::error::Missing secret ${v}. Add it under Settings → Secrets → Actions." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
cat > environment.go <<EOF
|
||||||
|
package main
|
||||||
|
|
||||||
|
var Environment = EnvironmentStruct{
|
||||||
|
ANILIST_SECRET_TOKEN: "${ANILIST_SECRET_TOKEN}",
|
||||||
|
ANILIST_APP_ID: "${ANILIST_APP_ID}",
|
||||||
|
ANILIST_APP_NAME: "${ANILIST_APP_NAME}",
|
||||||
|
ANILIST_CALLBACK_URI: "${ANILIST_CALLBACK_URI}",
|
||||||
|
SIMKL_CLIENT_ID: "${SIMKL_CLIENT_ID}",
|
||||||
|
SIMKL_CLIENT_SECRET: "${SIMKL_CLIENT_SECRET}",
|
||||||
|
SIMKL_CALLBACK_URI: "${SIMKL_CALLBACK_URI}",
|
||||||
|
MAL_CLIENT_ID: "${MAL_CLIENT_ID}",
|
||||||
|
MAL_CLIENT_SECRET: "${MAL_CLIENT_SECRET}",
|
||||||
|
MAL_CALLBACK_URI: "${MAL_CALLBACK_URI}",
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Wrote environment.go from secrets."
|
||||||
|
|
||||||
|
- name: Build Linux binary
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
export PATH="${HOME}/go/bin:${PATH}"
|
||||||
|
make build
|
||||||
|
test -x build/bin/AniTrack || { echo "::error::build/bin/AniTrack missing after make build" >&2; exit 1; }
|
||||||
|
|
||||||
|
- name: Package release archive
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
: "${VERSION:?VERSION missing from version-guard step}"
|
||||||
|
STAGE="dist/AniTrack-${VERSION}"
|
||||||
|
rm -rf dist "AniTrack-${VERSION}.tar.gz"
|
||||||
|
mkdir -p "${STAGE}/bin"
|
||||||
|
cp build/bin/AniTrack "${STAGE}/bin/"
|
||||||
|
cp -r build/icon "${STAGE}/"
|
||||||
|
cp build/AniTrack.desktop build/install_linux.sh build/README.md "${STAGE}/"
|
||||||
|
chmod +x "${STAGE}/bin/AniTrack" "${STAGE}/install_linux.sh"
|
||||||
|
tar -czf "AniTrack-${VERSION}.tar.gz" -C dist "AniTrack-${VERSION}"
|
||||||
|
tar tzf "AniTrack-${VERSION}.tar.gz"
|
||||||
|
echo "ARCHIVE=AniTrack-${VERSION}.tar.gz" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Create Gitea Release
|
||||||
|
env:
|
||||||
|
# REGISTRY_TOKEN is reused for release creation because Gitea's auto
|
||||||
|
# token cannot create releases on this instance. The PAT must carry
|
||||||
|
# write:repository scope. Idempotent: re-runs update an existing
|
||||||
|
# release for this tag instead of failing with 409. On any HTTP error
|
||||||
|
# the API response body is printed so a 403 names the missing scope.
|
||||||
|
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
: "${TAG:?TAG is required}"
|
||||||
|
: "${VERSION:?VERSION missing from version-guard step}"
|
||||||
|
API="https://git.linuxhg.com/api/v1/repos/${REPO}/releases"
|
||||||
|
AUTH="Authorization: token ${TOKEN}"
|
||||||
|
# Release body = the annotated tag's message (the git-cliff notes).
|
||||||
|
# Manual test tags without an annotation fall back to the tag name.
|
||||||
|
BODY="$(git tag -l --format='%(contents)' "${TAG}")"
|
||||||
|
if [ -z "$(printf '%s' "${BODY}" | tr -d '[:space:]')" ]; then
|
||||||
|
BODY="${TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tags containing a '-' (e.g. 1.6.7-rc1) are published as pre-releases.
|
||||||
|
PRE="false"; case "${TAG}" in *-*) PRE="true";; esac
|
||||||
|
|
||||||
|
PAYLOAD=$(jq -n \
|
||||||
|
--arg t "${TAG}" --arg n "AniTrack-${VERSION}" --arg b "${BODY}" --argjson p "${PRE}" \
|
||||||
|
'{tag_name:$t, name:$n, body:$b, draft:false, prerelease:$p}')
|
||||||
|
|
||||||
|
# POST/PATCH the release, surfacing Gitea's error message on failure
|
||||||
|
# (e.g. "token does not have write scope") instead of failing silently.
|
||||||
|
api_call() {
|
||||||
|
local method="$1" url="$2" resp code rbody
|
||||||
|
resp="$(curl -sS -w '\n%{http_code}' -X "${method}" \
|
||||||
|
-H "${AUTH}" -H "Content-Type: application/json" \
|
||||||
|
-d "${PAYLOAD}" "${url}")"
|
||||||
|
code="$(printf '%s' "${resp}" | tail -n1)"
|
||||||
|
rbody="$(printf '%s' "${resp}" | sed '$d')"
|
||||||
|
if [ "${code}" -ge 400 ]; then
|
||||||
|
echo "::error::Release API ${code} (${method} ${url}): ${rbody}" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
EXISTING_ID="$(curl -sS -H "${AUTH}" "${API}/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null || true)"
|
||||||
|
if [ -n "${EXISTING_ID}" ]; then
|
||||||
|
api_call PATCH "${API}/${EXISTING_ID}"
|
||||||
|
echo "Updated existing release id=${EXISTING_ID} for ${TAG}"
|
||||||
|
else
|
||||||
|
api_call POST "${API}"
|
||||||
|
echo "Created new release for ${TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload release archive
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
: "${TAG:?TAG is required}"
|
||||||
|
: "${ARCHIVE:?ARCHIVE missing from packaging step}"
|
||||||
|
API="https://git.linuxhg.com/api/v1/repos/${REPO}/releases"
|
||||||
|
AUTH="Authorization: token ${TOKEN}"
|
||||||
|
test -f "${ARCHIVE}" || { echo "::error::${ARCHIVE} not found" >&2; exit 1; }
|
||||||
|
|
||||||
|
RID="$(curl -sS -H "${AUTH}" "${API}/tags/${TAG}" | jq -r '.id // empty')"
|
||||||
|
if [ -z "${RID}" ]; then
|
||||||
|
echo "::error::No release found for tag ${TAG} after create step" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace a same-named asset so re-runs stay idempotent.
|
||||||
|
AID="$(curl -sS -H "${AUTH}" "${API}/${RID}/assets" | jq -r --arg n "${ARCHIVE}" '.[] | select(.name==$n) | .id // empty')"
|
||||||
|
if [ -n "${AID}" ]; then
|
||||||
|
curl -sS -X DELETE -H "${AUTH}" "${API}/${RID}/assets/${AID}" >/dev/null
|
||||||
|
echo "Deleted existing asset id=${AID} (${ARCHIVE})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
resp="$(curl -sS -w '\n%{http_code}' -X POST -H "${AUTH}" \
|
||||||
|
-F "attachment=@${ARCHIVE}" "${API}/${RID}/assets?name=${ARCHIVE}")"
|
||||||
|
code="$(printf '%s' "${resp}" | tail -n1)"
|
||||||
|
rbody="$(printf '%s' "${resp}" | sed '$d')"
|
||||||
|
if [ "${code}" -ge 400 ]; then
|
||||||
|
echo "::error::Asset upload ${code}: ${rbody}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Uploaded ${ARCHIVE} to release id=${RID}"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
TAGS := webkit2_41
|
TAGS := webkit2_41
|
||||||
|
|
||||||
.PHONY: dev build clean
|
.PHONY: dev build clean release
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
wails dev -tags $(TAGS)
|
wails dev -tags $(TAGS)
|
||||||
@@ -10,3 +10,42 @@ build:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build/bin/*
|
rm -rf build/bin/*
|
||||||
|
|
||||||
|
# Create a version commit (wails.json bump, committed and pushed) plus an
|
||||||
|
# annotated version tag carrying auto-generated release notes (git-cliff),
|
||||||
|
# and push both. The tag push triggers .gitea/workflows/release.yml, which
|
||||||
|
# verifies wails.json matches the tag, builds via `make build`, packages
|
||||||
|
# AniTrack-<VERSION>.tar.gz from build/, and publishes a Gitea Release
|
||||||
|
# named AniTrack-<VERSION> with the archive attached. Notes come entirely
|
||||||
|
# from Conventional Commits — no hand-written message required.
|
||||||
|
#
|
||||||
|
# git-cliff's --latest needs the tag to exist to scope the notes, so we
|
||||||
|
# create a throwaway lightweight tag, generate the notes, replace it with
|
||||||
|
# an annotated tag, then push. --cleanup=verbatim keeps the markdown "###"
|
||||||
|
# group headers (git's default cleanup would strip lines starting with "#").
|
||||||
|
#
|
||||||
|
# Tags are plain versions (1.6.7) to match wails.json productVersion and the
|
||||||
|
# existing tag history. Pre-releases are created by tagging manually with a
|
||||||
|
# suffix (e.g. 1.6.7-rc1 on top of the bumped commit) — the workflow marks
|
||||||
|
# those as prerelease. Use ./release as a shortcut.
|
||||||
|
#
|
||||||
|
# Requires git-cliff: https://git-cliff.org/install
|
||||||
|
# Usage: make release VERSION=1.6.7
|
||||||
|
release:
|
||||||
|
@test -n "$(VERSION)" || { echo "Usage: make release VERSION=1.6.7"; exit 1; }
|
||||||
|
@echo "$(VERSION)" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$$' || { echo "VERSION must be plain semver like 1.6.7 (no v prefix, no AniTrack- prefix, no suffix)"; exit 1; }
|
||||||
|
@command -v git-cliff >/dev/null 2>&1 || { echo "git-cliff not found — install: https://git-cliff.org/install"; exit 1; }
|
||||||
|
@command -v python3 >/dev/null 2>&1 || { echo "python3 not found — required to bump wails.json"; exit 1; }
|
||||||
|
@git diff --quiet && git diff --cached --quiet || { echo "Working tree dirty — commit or stash first"; exit 1; }
|
||||||
|
@if git rev-parse "$(VERSION)" >/dev/null 2>&1; then echo "Tag $(VERSION) already exists locally — delete it first: git tag -d $(VERSION)"; exit 1; fi
|
||||||
|
@echo "Bumping wails.json to $(VERSION)..."
|
||||||
|
@python3 -c "import json; p='wails.json'; d=json.load(open(p)); d['info']['productVersion']='$(VERSION)'; json.dump(d, open(p,'w'), indent=2); open(p,'a').write('\n')"
|
||||||
|
@git add wails.json
|
||||||
|
@git commit -m "chore(release): bump version to $(VERSION)"
|
||||||
|
@echo "Generating release notes for $(VERSION)..."
|
||||||
|
@git tag "$(VERSION)" HEAD && \
|
||||||
|
(git cliff --latest --config cliff.toml > .release-notes.tmp && git tag -d "$(VERSION)" >/dev/null) || \
|
||||||
|
{ git tag -d "$(VERSION)" >/dev/null 2>&1; rm -f .release-notes.tmp; echo "git-cliff failed"; exit 1; }
|
||||||
|
@git tag -a --cleanup=verbatim -F .release-notes.tmp "$(VERSION)" HEAD && rm -f .release-notes.tmp
|
||||||
|
@git push origin main "$(VERSION)"
|
||||||
|
@echo "Pushed $(VERSION) — Gitea Actions will build, package, and publish AniTrack-$(VERSION).tar.gz."
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
# git-cliff configuration — generates the body of each Gitea Release from
|
||||||
|
# Conventional Commits accumulated since the previous tag. Invoked locally by
|
||||||
|
# `make release VERSION=...`; the annotated tag message becomes the Release
|
||||||
|
# body in .gitea/workflows/release.yml. Tags are plain versions (1.6.7).
|
||||||
|
# Docs: https://git-cliff.org/docs/configuration
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
header = ""
|
||||||
|
body = """
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}\
|
||||||
|
### {{ group | upper_first }}
|
||||||
|
{% for commit in commits %}\
|
||||||
|
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}{{ commit.message | upper_first }} ({{ commit.id | truncate(length=7, end="") }})
|
||||||
|
{% endfor %}\
|
||||||
|
{% endfor %}\
|
||||||
|
"""
|
||||||
|
trim = true
|
||||||
|
footer = ""
|
||||||
|
|
||||||
|
[git]
|
||||||
|
conventional_commits = true
|
||||||
|
filter_unconventional = false
|
||||||
|
require_conventional = false
|
||||||
|
split_commits = false
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "Features" },
|
||||||
|
{ message = "^fix", group = "Bug Fixes" },
|
||||||
|
{ message = "^perf", group = "Performance" },
|
||||||
|
{ message = "^refactor", group = "Refactor" },
|
||||||
|
{ message = "^docs", group = "Documentation" },
|
||||||
|
{ message = "^test", group = "Tests" },
|
||||||
|
{ message = "^chore|^ci", group = "Miscellaneous Tasks" },
|
||||||
|
{ message = ".*", group = "Other" },
|
||||||
|
]
|
||||||
|
filter_commits = false
|
||||||
|
tag_pattern = "[0-9].*"
|
||||||
|
sort_commits = "oldest"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Project-attached wrapper around `make release` so you can run:
|
||||||
|
# ./release 1.6.7 (or) ./release v1.6.7 (or) ./release AniTrack-1.6.7
|
||||||
|
# instead of:
|
||||||
|
# make release VERSION=1.6.7
|
||||||
|
# Lives in the repo (no machine-specific alias needed). Tags are plain
|
||||||
|
# versions (1.6.7) to match wails.json productVersion.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
[ "$#" -ge 1 ] || { echo "Usage: ./release 1.6.7" >&2; exit 1; }
|
||||||
|
|
||||||
|
# Normalize "v1.6.7" or "AniTrack-1.6.7" down to plain "1.6.7" (the Makefile
|
||||||
|
# rejects anything that is not plain semver, so this just saves typing).
|
||||||
|
VERSION="${1#v}"
|
||||||
|
VERSION="${VERSION#AniTrack-}"
|
||||||
|
|
||||||
|
exec make release "VERSION=${VERSION}"
|
||||||
Reference in New Issue
Block a user