docs: add CI/release documentation and ignore dist directory
Tests / Go and GTK tests (push) Failing after 1m8s
Tests / Go and GTK tests (push) Failing after 1m8s
Add `/dist/` to `.gitignore` to exclude locally built distribution artifacts. Document the Gitea Actions workflow, release tagging, and branch protection setup in the README.
This commit is contained in:
@@ -0,0 +1,115 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
code: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Tests before release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: registry.fedoraproject.org/fedora:44
|
||||||
|
steps:
|
||||||
|
- name: Validate release tag
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -Eeuo pipefail
|
||||||
|
[[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
|
||||||
|
printf 'Tag must match vMAJOR.MINOR.BUG; got %s\n' "${GITHUB_REF_NAME}" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: >-
|
||||||
|
dnf install -y
|
||||||
|
bzip2 curl gcc gcc-c++ git gtk4-devel gtk4-layer-shell-devel
|
||||||
|
jq libX11-devel libXfixes-devel pkgconf-pkg-config
|
||||||
|
pulseaudio-utils ShellCheck tar gzip binutils
|
||||||
|
|
||||||
|
- name: Check out repository
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install the Go version from go.mod
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -Eeuo pipefail
|
||||||
|
go_version="$(awk '$1 == "go" { print $2 }' go.mod)"
|
||||||
|
curl --fail --location --silent --show-error \
|
||||||
|
"https://go.dev/dl/go${go_version}.linux-amd64.tar.gz" \
|
||||||
|
--output /tmp/go.tar.gz
|
||||||
|
rm -rf /usr/local/go
|
||||||
|
tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||||
|
ln -sf /usr/local/go/bin/go /usr/local/bin/go
|
||||||
|
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||||
|
go version
|
||||||
|
|
||||||
|
- name: Run tests and static checks
|
||||||
|
run: ./scripts/ci/test.sh
|
||||||
|
|
||||||
|
publish:
|
||||||
|
name: Build and publish release
|
||||||
|
needs: test
|
||||||
|
permissions:
|
||||||
|
code: read
|
||||||
|
releases: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: registry.fedoraproject.org/fedora:44
|
||||||
|
steps:
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: >-
|
||||||
|
dnf install -y
|
||||||
|
bzip2 curl gcc gcc-c++ git gtk4-devel gtk4-layer-shell-devel
|
||||||
|
jq libX11-devel libXfixes-devel pkgconf-pkg-config
|
||||||
|
pulseaudio-utils ShellCheck tar gzip binutils
|
||||||
|
|
||||||
|
- name: Check out repository and tags
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install the Go version from go.mod
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -Eeuo pipefail
|
||||||
|
go_version="$(awk '$1 == "go" { print $2 }' go.mod)"
|
||||||
|
curl --fail --location --silent --show-error \
|
||||||
|
"https://go.dev/dl/go${go_version}.linux-amd64.tar.gz" \
|
||||||
|
--output /tmp/go.tar.gz
|
||||||
|
rm -rf /usr/local/go
|
||||||
|
tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||||
|
ln -sf /usr/local/go/bin/go /usr/local/bin/go
|
||||||
|
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||||
|
go version
|
||||||
|
|
||||||
|
- name: Build portable release archive
|
||||||
|
run: ./scripts/ci/package-release.sh "${GITHUB_REF_NAME}"
|
||||||
|
|
||||||
|
- name: Generate release notes
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -Eeuo pipefail
|
||||||
|
previous_tag="$(git describe --tags --abbrev=0 "${GITHUB_REF_NAME}^" --match 'v[0-9]*' 2>/dev/null || true)"
|
||||||
|
{
|
||||||
|
printf 'Automated Captioneer release for `%s`.\n\n' "${GITHUB_REF_NAME}"
|
||||||
|
printf 'The Linux x86_64 archive contains both Captioneer commands and their Sherpa/ONNX native libraries. Models are downloaded separately with `scripts/download-models.sh`.\n'
|
||||||
|
if [[ -n "$previous_tag" ]]; then
|
||||||
|
printf '\nChanges since `%s`:\n\n' "$previous_tag"
|
||||||
|
git log --no-merges --pretty='- %s (`%h`)' "${previous_tag}..${GITHUB_REF_NAME}"
|
||||||
|
fi
|
||||||
|
} > dist/release-notes.md
|
||||||
|
|
||||||
|
- name: Publish Gitea release
|
||||||
|
env:
|
||||||
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
|
GITEA_REPOSITORY: ${{ gitea.repository }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
RELEASE_TAG: ${{ gitea.ref_name }}
|
||||||
|
RELEASE_NOTES: dist/release-notes.md
|
||||||
|
run: >-
|
||||||
|
./scripts/ci/publish-release.sh
|
||||||
|
"dist/captioneer-${GITHUB_REF_NAME}-linux-amd64.tar.gz"
|
||||||
|
"dist/captioneer-${GITHUB_REF_NAME}-linux-amd64.tar.gz.sha256"
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
name: Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
code: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Go and GTK tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: registry.fedoraproject.org/fedora:44
|
||||||
|
steps:
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: >-
|
||||||
|
dnf install -y
|
||||||
|
bzip2 curl gcc gcc-c++ git gtk4-devel gtk4-layer-shell-devel
|
||||||
|
jq libX11-devel libXfixes-devel pkgconf-pkg-config
|
||||||
|
pulseaudio-utils ShellCheck tar gzip binutils
|
||||||
|
|
||||||
|
- name: Check out repository
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install the Go version from go.mod
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -Eeuo pipefail
|
||||||
|
go_version="$(awk '$1 == "go" { print $2 }' go.mod)"
|
||||||
|
curl --fail --location --silent --show-error \
|
||||||
|
"https://go.dev/dl/go${go_version}.linux-amd64.tar.gz" \
|
||||||
|
--output /tmp/go.tar.gz
|
||||||
|
rm -rf /usr/local/go
|
||||||
|
tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||||
|
ln -sf /usr/local/go/bin/go /usr/local/bin/go
|
||||||
|
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||||
|
go version
|
||||||
|
|
||||||
|
- name: Run tests and static checks
|
||||||
|
run: ./scripts/ci/test.sh
|
||||||
@@ -5,3 +5,4 @@ models/silero_vad_v5.onnx
|
|||||||
# Locally built executable.
|
# Locally built executable.
|
||||||
/captioneer
|
/captioneer
|
||||||
/build/
|
/build/
|
||||||
|
/dist/
|
||||||
|
|||||||
@@ -201,6 +201,21 @@ distrobox enter --no-workdir captioneer-dev -- bash -lc '
|
|||||||
|
|
||||||
Run this from the repository root. The build and run helpers resolve that path automatically.
|
Run this from the repository root. The build and run helpers resolve that path automatically.
|
||||||
|
|
||||||
|
## Gitea Actions and releases
|
||||||
|
|
||||||
|
The `Tests` workflow runs the normal and GTK-tagged Go tests, `go vet`, and ShellCheck for every pull request and branch push. To make it mandatory for pull requests, open the repository's **Settings → Branches**, edit the protection rule for `master`, enable required status checks, and select **Tests / Go and GTK tests** after its first run. Workflow files can report the check, but the branch-protection rule is what prevents merging when it fails.
|
||||||
|
|
||||||
|
Pushing a tag that exactly follows `vMAJOR.MINOR.BUG` runs the same test suite first, then builds and publishes a Gitea release:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git tag v1.3.519
|
||||||
|
git push origin v1.3.519
|
||||||
|
```
|
||||||
|
|
||||||
|
The release contains a checksummed Linux x86_64 archive with `captioneer`, `captioneer-desktop`, the required Sherpa/ONNX shared libraries, the model download script, the README, and the license. The desktop command still requires GTK4 and GTK4 Layer Shell runtime libraries on the destination system.
|
||||||
|
|
||||||
|
The release workflow uses Gitea's built-in `GITEA_TOKEN`; no personal token is required. In **Settings → Actions → General**, allow the workflow token `Read` access to code and `Write` access to releases. Gitea clamps workflow permissions to those repository settings, so a more restrictive maximum produces an actionable HTTP 403 during publishing.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Captioneer is licensed under the [Apache License 2.0](LICENSE). Sherpa-Onnx is Apache-2.0 licensed, GTK4 is LGPL-2.1-or-later, and GTK4 Layer Shell is MIT licensed. Captioneer links to the system GTK libraries rather than copying their source into the project.
|
Captioneer is licensed under the [Apache License 2.0](LICENSE). Sherpa-Onnx is Apache-2.0 licensed, GTK4 is LGPL-2.1-or-later, and GTK4 Layer Shell is MIT licensed. Captioneer links to the system GTK libraries rather than copying their source into the project.
|
||||||
|
|||||||
Executable
+51
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd -P)"
|
||||||
|
cd -- "$repo_root"
|
||||||
|
|
||||||
|
tag=${1:-}
|
||||||
|
if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
printf 'captioneer: release tag must match vMAJOR.MINOR.BUG, got %q\n' "$tag" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
platform=linux-amd64
|
||||||
|
archive_name="captioneer-${tag}-${platform}.tar.gz"
|
||||||
|
package_name="captioneer-${tag}-${platform}"
|
||||||
|
package_dir="dist/$package_name"
|
||||||
|
|
||||||
|
rm -rf -- "$package_dir"
|
||||||
|
rm -f -- "dist/$archive_name" "dist/$archive_name.sha256"
|
||||||
|
mkdir -p -- "$package_dir/lib" "$package_dir/scripts"
|
||||||
|
|
||||||
|
# The Sherpa Go module embeds an absolute build-machine RPATH. Add a portable
|
||||||
|
# fallback so the bundled native libraries resolve beside the extracted tools.
|
||||||
|
# shellcheck disable=SC2016 # $ORIGIN must remain literal for the ELF loader.
|
||||||
|
export CGO_LDFLAGS='-Wl,-rpath,$ORIGIN/lib'
|
||||||
|
go build -trimpath -o "$package_dir/captioneer" ./src/cmd/captioneer
|
||||||
|
go build -trimpath -tags gtk -o "$package_dir/captioneer-desktop" ./src/cmd/captioneer-desktop
|
||||||
|
|
||||||
|
sherpa_dir="$(go list -m -f '{{.Dir}}' github.com/k2-fsa/sherpa-onnx-go-linux)"
|
||||||
|
sherpa_lib_dir="$sherpa_dir/lib/x86_64-unknown-linux-gnu"
|
||||||
|
cp -- "$sherpa_lib_dir/libsherpa-onnx-c-api.so" "$package_dir/lib/"
|
||||||
|
cp -- "$sherpa_lib_dir/libonnxruntime.so" "$package_dir/lib/"
|
||||||
|
cp -- README.md LICENSE "$package_dir/"
|
||||||
|
cp -- scripts/download-models.sh "$package_dir/scripts/"
|
||||||
|
|
||||||
|
for executable in captioneer captioneer-desktop; do
|
||||||
|
# shellcheck disable=SC2016 # Verify the literal ELF-loader token.
|
||||||
|
if ! readelf -d "$package_dir/$executable" | grep -Fq '$ORIGIN/lib'; then
|
||||||
|
printf 'captioneer: %s is missing the portable native-library RPATH\n' "$executable" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
tar -C dist -czf "dist/$archive_name" "$package_name"
|
||||||
|
(
|
||||||
|
cd -- dist
|
||||||
|
sha256sum "$archive_name" > "$archive_name.sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
printf '%s\n' "$repo_root/dist/$archive_name"
|
||||||
|
printf '%s\n' "$repo_root/dist/$archive_name.sha256"
|
||||||
Executable
+80
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
: "${GITEA_API_URL:?GITEA_API_URL is required}"
|
||||||
|
: "${GITEA_REPOSITORY:?GITEA_REPOSITORY is required}"
|
||||||
|
: "${GITEA_TOKEN:?GITEA_TOKEN is required}"
|
||||||
|
: "${RELEASE_TAG:?RELEASE_TAG is required}"
|
||||||
|
: "${RELEASE_NOTES:?RELEASE_NOTES is required}"
|
||||||
|
|
||||||
|
if [[ ! "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
printf 'captioneer: release tag must match vMAJOR.MINOR.BUG, got %q\n' "$RELEASE_TAG" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if (( $# == 0 )); then
|
||||||
|
printf 'captioneer: at least one release asset is required\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for asset in "$@"; do
|
||||||
|
[[ -f "$asset" ]] || { printf 'captioneer: release asset not found: %s\n' "$asset" >&2; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
api_base="${GITEA_API_URL%/}/repos/$GITEA_REPOSITORY"
|
||||||
|
authorization="Authorization: token $GITEA_TOKEN"
|
||||||
|
release_response="$(mktemp)"
|
||||||
|
trap 'rm -f -- "$release_response"' EXIT
|
||||||
|
|
||||||
|
status="$(curl --silent --show-error --output "$release_response" --write-out '%{http_code}' \
|
||||||
|
--header "$authorization" \
|
||||||
|
"$api_base/releases/tags/$RELEASE_TAG")"
|
||||||
|
|
||||||
|
release_payload="$(jq -n \
|
||||||
|
--arg tag "$RELEASE_TAG" \
|
||||||
|
--arg name "Captioneer $RELEASE_TAG" \
|
||||||
|
--rawfile body "$RELEASE_NOTES" \
|
||||||
|
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}')"
|
||||||
|
|
||||||
|
case "$status" in
|
||||||
|
200)
|
||||||
|
release_id="$(jq -er '.id' "$release_response")"
|
||||||
|
curl --fail-with-body --silent --show-error \
|
||||||
|
--request PATCH \
|
||||||
|
--header "$authorization" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data "$release_payload" \
|
||||||
|
"$api_base/releases/$release_id" > "$release_response"
|
||||||
|
;;
|
||||||
|
404)
|
||||||
|
curl --fail-with-body --silent --show-error \
|
||||||
|
--request POST \
|
||||||
|
--header "$authorization" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data "$release_payload" \
|
||||||
|
"$api_base/releases" > "$release_response"
|
||||||
|
release_id="$(jq -er '.id' "$release_response")"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf 'captioneer: Gitea release lookup failed with HTTP %s\n' "$status" >&2
|
||||||
|
cat "$release_response" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for asset in "$@"; do
|
||||||
|
asset_name="$(basename -- "$asset")"
|
||||||
|
while IFS= read -r attachment_id; do
|
||||||
|
[[ -n "$attachment_id" ]] || continue
|
||||||
|
curl --fail-with-body --silent --show-error \
|
||||||
|
--request DELETE \
|
||||||
|
--header "$authorization" \
|
||||||
|
"$api_base/releases/$release_id/assets/$attachment_id" >/dev/null
|
||||||
|
done < <(jq -r --arg name "$asset_name" '.assets[]? | select(.name == $name) | .id' "$release_response")
|
||||||
|
|
||||||
|
curl --fail-with-body --silent --show-error \
|
||||||
|
--request POST \
|
||||||
|
--header "$authorization" \
|
||||||
|
--form "attachment=@$asset" \
|
||||||
|
"$api_base/releases/$release_id/assets?name=$asset_name" >/dev/null
|
||||||
|
printf 'Uploaded %s\n' "$asset_name"
|
||||||
|
done
|
||||||
Executable
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd -P)"
|
||||||
|
cd -- "$repo_root"
|
||||||
|
|
||||||
|
go test ./...
|
||||||
|
go test -tags gtk ./...
|
||||||
|
go vet ./...
|
||||||
|
go vet -tags gtk ./...
|
||||||
|
|
||||||
|
shellcheck \
|
||||||
|
scripts/download-models.sh \
|
||||||
|
scripts/distrobox/common.sh \
|
||||||
|
scripts/distrobox/build.sh \
|
||||||
|
scripts/distrobox/run.sh \
|
||||||
|
scripts/ci/test.sh \
|
||||||
|
scripts/ci/package-release.sh \
|
||||||
|
scripts/ci/publish-release.sh
|
||||||
Reference in New Issue
Block a user