Compare commits
1 Commits
ci/bundle-
...
fix/releas
| Author | SHA1 | Date | |
|---|---|---|---|
| ea7e491ba3 |
@@ -13,23 +13,15 @@
|
||||
# byte-identical.
|
||||
#
|
||||
# ── Where it is published, and why not as a release ──────────────────────────
|
||||
# Bundles are COMMITTED to this repo, on their own `bundles` branch, at its root:
|
||||
# Bundles are COMMITTED to this repo under bundles/:
|
||||
#
|
||||
# current.json the bundle the installer uses by default
|
||||
# bundle-<tag>.json every bundle ever published, kept for --bundle
|
||||
# bundles/current.json the bundle the installer uses by default
|
||||
# bundles/bundle-<tag>.json every bundle ever published, kept for --bundle
|
||||
#
|
||||
# so the installer's two fetches are plain anonymous raw URLs on a public repo:
|
||||
#
|
||||
# https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/bundles/current.json
|
||||
# https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/bundles/bundle-2026.08.04.json
|
||||
#
|
||||
# A BRANCH, not `main`, because `main` is protected and this job is unattended:
|
||||
# the pre-receive hook declines a push from CI, which is not a thing a nightly
|
||||
# cron can resolve. Publishing to a branch of its own keeps everything the
|
||||
# original choice was for — a reviewable diff, a git history of the compat
|
||||
# matrix, plain raw URLs, no auth on the shard host — and needs no protection
|
||||
# exception. The alternative, whitelisting a scheduled job for pushes to the
|
||||
# default branch, buys nothing this does not.
|
||||
# https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/main/bundles/current.json
|
||||
# https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/main/bundles/bundle-2026.08.04.json
|
||||
#
|
||||
# The obvious alternative — one Gitea release per bundle — was rejected because
|
||||
# it collides with this repo's own product. release.yml publishes the installer
|
||||
@@ -38,8 +30,8 @@
|
||||
# intermittently resolve to a release containing no installer binary. Committing
|
||||
# also gets a reviewable diff and a git history of the compat matrix for free.
|
||||
#
|
||||
# `main` is never pushed to by this workflow. (release.yml does not push to it
|
||||
# either — it tags and lets the release API do the rest.)
|
||||
# The push to `main` needs no new branch-protection exception: release.yml's
|
||||
# version-bump commit already requires REGISTRY_USER to be able to push here.
|
||||
#
|
||||
# ── Triggers (PLAN.md §7.2) ──────────────────────────────────────────────────
|
||||
# workflow_dispatch — POSTed by link's and servuo-plugins' release workflows
|
||||
@@ -94,44 +86,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
# Full history: the publish step rebases onto the bundles branch if another
|
||||
# run landed while this one was composing, and a depth-1 clone has no base
|
||||
# to rebase onto.
|
||||
- name: Check out the repository
|
||||
# Full history: the push step rebases onto main if release.yml's version
|
||||
# bump landed while this job was composing, and a depth-1 clone has no
|
||||
# base to rebase onto.
|
||||
- name: Check out the bundles directory
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# The published bundles live on their own branch (see the header), so they
|
||||
# are materialized into a worktree rather than being part of the checkout.
|
||||
# Everything downstream reads and writes `published/`, which means the
|
||||
# ".2 suffix" scan and the idempotence check both see what is actually
|
||||
# published rather than a stale copy on main.
|
||||
- name: Materialize the bundles branch
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git config user.name "installer-ci"
|
||||
git config user.email "ci@whitlocktech.com"
|
||||
# `prune` matters on a re-run in an existing checkout: removing the
|
||||
# directory leaves the worktree registered, and `worktree add` then
|
||||
# refuses the path. CI checks out fresh every time, so this only shows
|
||||
# up when driving the job by hand — which is how it is tested.
|
||||
rm -rf published
|
||||
git worktree prune
|
||||
if git ls-remote --exit-code --heads origin bundles >/dev/null 2>&1; then
|
||||
git fetch origin bundles
|
||||
git worktree add -B bundles published origin/bundles
|
||||
echo "==> bundles branch: $(ls published/*.json 2>/dev/null | wc -l) published bundle(s)"
|
||||
else
|
||||
# First run. A root commit with an empty tree gives the worktree a
|
||||
# branch to sit on without inheriting main's history, which has
|
||||
# nothing to do with the compat matrix.
|
||||
EMPTY_TREE="$(git hash-object -t tree /dev/null)"
|
||||
ROOT="$(git commit-tree "$EMPTY_TREE" -m 'chore(bundle): start the bundles branch')"
|
||||
git worktree add -B bundles published "$ROOT"
|
||||
echo "==> bundles branch does not exist yet; it will be created by the first publish"
|
||||
fi
|
||||
|
||||
- name: Install jq and curl
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -214,15 +176,14 @@ jobs:
|
||||
# a target to link's release.yml (macOS, a Windows arm64) surfaces here
|
||||
# as a red run, rather than being silently dropped from every bundle.
|
||||
#
|
||||
# linux-aarch64 was recognized here one merge BEFORE link published one
|
||||
# (PLAN.md §5.2, steps 1 and 3). That order was forced by the two rules
|
||||
# linux-aarch64 is recognized here BEFORE link publishes one
|
||||
# (PLAN.md §5.2, step 1 of 4). That order is forced by the two rules
|
||||
# below being strict in opposite directions: an unknown name fails the
|
||||
# run, and a missing REQUIRED key fails it too. So the name had to be
|
||||
# taught before the release that carried it, and the key could only be
|
||||
# required after — requiring it first would have failed every bundle
|
||||
# for as long as the gap lasted. link v1.1.1 ships the binary, so the
|
||||
# key is now required: a dropped target reddens this job instead of
|
||||
# vanishing from every bundle.
|
||||
# run, and a missing REQUIRED key fails it too. So the name has to be
|
||||
# taught before the release that carries it, and the key can only be
|
||||
# required after — requiring it first would fail every bundle for as
|
||||
# long as the gap lasts. Step 3 promotes it into REQUIRED once a link
|
||||
# release actually ships the binary.
|
||||
: > work/link-platforms.tsv
|
||||
while IFS="$(printf '\t')" read -r NAME URL; do
|
||||
[ -n "$NAME" ] || continue
|
||||
@@ -235,9 +196,9 @@ jobs:
|
||||
printf '%s\t%s\t%s\t%s\n' "$PLAT" "$NAME" "$URL" \
|
||||
"$(sha256sum "work/link/${NAME}" | cut -d' ' -f1)" >> work/link-platforms.tsv
|
||||
done < work/link/asset-list.tsv
|
||||
for REQUIRED in linux-x86_64 linux-aarch64 windows-x86_64; do
|
||||
for REQUIRED in linux-x86_64 windows-x86_64; do
|
||||
grep -q "^${REQUIRED}$(printf '\t')" work/link-platforms.tsv \
|
||||
|| fail "link release is missing a ${REQUIRED} binary; the installer ships for all three"
|
||||
|| fail "link release is missing a ${REQUIRED} binary; the installer ships for both"
|
||||
done
|
||||
|
||||
# The overlay release carries exactly one artifact: the tarball.
|
||||
@@ -379,8 +340,8 @@ jobs:
|
||||
# commit a dated duplicate of the same matrix forever. Compare only
|
||||
# what the installer would actually act on.
|
||||
CHANGED=true
|
||||
if [ -f published/current.json ]; then
|
||||
if jq -S 'del(.bundle, .generated)' published/current.json > work/old-content.json \
|
||||
if [ -f bundles/current.json ]; then
|
||||
if jq -S 'del(.bundle, .generated)' bundles/current.json > work/old-content.json \
|
||||
&& jq -S '.' work/content.json > work/new-content.json \
|
||||
&& cmp -s work/old-content.json work/new-content.json; then
|
||||
CHANGED=false
|
||||
@@ -389,7 +350,7 @@ jobs:
|
||||
echo "changed=${CHANGED}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
if [ "$CHANGED" = false ]; then
|
||||
echo "==> identical to the published current.json — nothing to publish."
|
||||
echo "==> identical to bundles/current.json — nothing to publish."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -399,14 +360,15 @@ jobs:
|
||||
# always names exactly one matrix and `--bundle` stays reproducible.
|
||||
BASE="$(date -u +%Y.%m.%d)"
|
||||
TAG="$BASE"; N=1
|
||||
while [ -f "published/bundle-${TAG}.json" ]; do
|
||||
while [ -f "bundles/bundle-${TAG}.json" ]; do
|
||||
N=$((N+1)); TAG="${BASE}.${N}"
|
||||
done
|
||||
|
||||
mkdir -p bundles
|
||||
jq --arg bundle "$TAG" --arg generated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
'{ schema: .schema, bundle: $bundle, generated: $generated } + del(.schema)' \
|
||||
work/content.json > "published/bundle-${TAG}.json"
|
||||
cp "published/bundle-${TAG}.json" published/current.json
|
||||
work/content.json > "bundles/bundle-${TAG}.json"
|
||||
cp "bundles/bundle-${TAG}.json" bundles/current.json
|
||||
|
||||
echo "bundle_tag=${TAG}" >> "$GITHUB_OUTPUT"
|
||||
echo "==> composed bundle ${TAG}"
|
||||
@@ -435,11 +397,9 @@ jobs:
|
||||
set -euo pipefail
|
||||
CI_TOKEN="$(printf '%s' "${REGISTRY_TOKEN:-}" | tr -d '\r\n')"
|
||||
# Warnings go to a FILE, not a step output. The job summary below
|
||||
# reads it with `cat`; interpolating a multi-line template value into
|
||||
# reads it with `cat`; interpolating a multi-line `${{ }}` value into
|
||||
# a shell string there would let any character in a commit-derived
|
||||
# message change what that script does. (Do not write that token
|
||||
# literally in a comment: the runner parses it, fails, and silently
|
||||
# skips the whole step.)
|
||||
# message change what that script does.
|
||||
: > work/stale-warnings.md
|
||||
|
||||
for pair in "${LINK_REPO}:${{ steps.resolve.outputs.link_tag }}" \
|
||||
@@ -520,25 +480,27 @@ jobs:
|
||||
# cannot be parsed").
|
||||
CI_USER="$(printf '%s' "${REGISTRY_USER}" | tr -d '\r\n')"
|
||||
CI_TOKEN="$(printf '%s' "${REGISTRY_TOKEN}" | tr -d '\r\n')"
|
||||
git config user.name "installer-ci"
|
||||
git config user.email "ci@whitlocktech.com"
|
||||
git remote set-url origin "https://${CI_USER}:${CI_TOKEN}@${GITEA_HOST}/${REPO}.git"
|
||||
|
||||
cd published
|
||||
git add -A
|
||||
git add bundles
|
||||
git commit -m "chore(bundle): publish ${TAG} (link ${{ steps.resolve.outputs.link_tag }}, overlay ${{ steps.resolve.outputs.overlay_tag }}, protocol ${{ steps.protocol.outputs.protocol }}) [skip ci]"
|
||||
|
||||
# Two runs can compose at once — a component release dispatches this
|
||||
# while the nightly cron is mid-flight — so losing the race is normal
|
||||
# rather than exceptional. Rebase and retry once instead of failing and
|
||||
# leaving the bundle unpublished until tomorrow. Every file here is a
|
||||
# bundle nobody else edits, and a bundle tag names exactly one matrix,
|
||||
# so a rebase cannot conflict.
|
||||
if ! git push origin bundles; then
|
||||
echo "::warning::push rejected (the bundles branch moved during compose) — rebasing and retrying once"
|
||||
git fetch origin bundles
|
||||
git rebase origin/bundles
|
||||
git push origin bundles
|
||||
# The checkout is a detached snapshot of main; push the commit at HEAD
|
||||
# to the branch the installer reads its raw URLs from. release.yml
|
||||
# pushes its version-bump commit to the same branch, so losing the
|
||||
# race is normal rather than exceptional — rebase and retry once
|
||||
# instead of failing and leaving the bundle unpublished until the
|
||||
# next cron. Only bundles/ is touched here, so a rebase over a bump
|
||||
# commit cannot conflict.
|
||||
if ! git push origin "HEAD:main"; then
|
||||
echo "::warning::push rejected (main moved during compose) — rebasing and retrying once"
|
||||
git fetch origin main
|
||||
git rebase origin/main
|
||||
git push origin "HEAD:main"
|
||||
fi
|
||||
echo "==> published bundle-${TAG}.json and current.json on the bundles branch"
|
||||
echo "==> published bundles/bundle-${TAG}.json and bundles/current.json"
|
||||
|
||||
- name: Job summary
|
||||
if: always()
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
# Prerequisites (Settings → Actions → Secrets on RunicGateway/installer):
|
||||
# REGISTRY_USER — Gitea username the token below belongs to
|
||||
# REGISTRY_TOKEN — Gitea access token with `write:repository`, so it can push
|
||||
# the bump commit + tag and create the release.
|
||||
# Also: `main` must accept a direct push from that user (disable branch
|
||||
# protection for it, or add it as an exception) — the bump commit lands on main.
|
||||
# the release tag and create the release.
|
||||
#
|
||||
# The bump commit carries `[skip ci]`, so it does not re-trigger this workflow.
|
||||
# `main` needs NO push exception: this workflow tags and publishes, and never
|
||||
# writes to a branch. Keeping it that way is deliberate — a first release that
|
||||
# depends on a write to a protected branch fails at the worst possible moment.
|
||||
|
||||
name: Release installer
|
||||
|
||||
@@ -66,7 +66,8 @@ env:
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
# Don't loop on our own bump commit (belt-and-suspenders with [skip ci]).
|
||||
# Vestigial since this workflow stopped writing a bump commit, and kept as
|
||||
# belt-and-braces in case one ever returns.
|
||||
# Quoted because the expression contains a colon (`chore(release):`), which an
|
||||
# unquoted YAML scalar would misparse as a mapping value.
|
||||
if: "${{ !contains(github.event.head_commit.message, 'chore(release): bump version') }}"
|
||||
@@ -300,33 +301,45 @@ jobs:
|
||||
ls -l dist && echo "----" && cat dist/SHA256SUMS
|
||||
|
||||
# ── RELEASE ENGINE: commit the bump, tag, push ───────────────────────
|
||||
- name: Commit version bump and push tag
|
||||
# Tag only — `main` is never pushed to.
|
||||
#
|
||||
# This step used to commit the version bump back to main first, and it has
|
||||
# never executed in any repo that carries it: an EMPTY template expression
|
||||
# written literally in the comment below (the `$`+`{{ }}` token, spelled
|
||||
# out here for that reason) makes the runner fail to build the script and
|
||||
# skip the step WITHOUT failing the job. link/release.yml carried the same
|
||||
# bug for six releases, which is why its Cargo.toml still says 0.1.0 while
|
||||
# its tags reach v1.1.1 — the release API creates the tag when it
|
||||
# publishes, so the pipeline worked by accident.
|
||||
#
|
||||
# It also would have been declined if it had run: `main` is protected, and
|
||||
# the bundle job proved that on 2026-08-05 (`pre-receive hook declined`).
|
||||
# A first release must not depend on a write to a protected branch.
|
||||
#
|
||||
# So the tag is the version, as in servuo-plugins. The version is still
|
||||
# written into Cargo.toml before building, so a released binary
|
||||
# self-reports correctly; it is simply not committed back. The next
|
||||
# version is computed from the newest tag, never from the file.
|
||||
- name: Push the release tag
|
||||
if: ${{ steps.plan.outputs.release == 'true' }}
|
||||
env:
|
||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.plan.outputs.version }}"
|
||||
TAG="${{ steps.plan.outputs.tag }}"
|
||||
# Secrets can arrive with a trailing newline (depending on how they were
|
||||
# pasted); a stray CR/LF corrupts the remote URL ("credential url cannot
|
||||
# be parsed"). Strip line breaks before building the URL. Passing them via
|
||||
# env (not inline ${{ }}) also keeps a newline from breaking this script.
|
||||
# be parsed"). Strip line breaks before building the URL. They are passed
|
||||
# via env rather than interpolated into this script, so a newline cannot
|
||||
# break it — do NOT write a template token literally in a comment here,
|
||||
# or the runner will skip this step without failing the job.
|
||||
CI_USER="$(printf '%s' "${REGISTRY_USER}" | tr -d '\r\n')"
|
||||
CI_TOKEN="$(printf '%s' "${REGISTRY_TOKEN}" | tr -d '\r\n')"
|
||||
git config user.name "installer-ci"
|
||||
git config user.email "ci@whitlocktech.com"
|
||||
git remote set-url origin \
|
||||
"https://${CI_USER}:${CI_TOKEN}@${GITEA_HOST}/${REPO}.git"
|
||||
|
||||
git add Cargo.toml Cargo.lock
|
||||
if ! git diff --cached --quiet; then
|
||||
git commit -m "chore(release): bump version to ${TAG} [skip ci]"
|
||||
git push origin "HEAD:main"
|
||||
else
|
||||
echo "Version unchanged (first release) — no bump commit needed."
|
||||
fi
|
||||
# The tag may already exist when finishing a run that died after
|
||||
# tagging (see the plan step). `git tag` on an existing name fails
|
||||
# under `set -e`; pushing an identical existing tag is a harmless
|
||||
|
||||
@@ -13,10 +13,7 @@ nightly, so a missed dispatch self-heals. A run that finds nothing changed write
|
||||
|
||||
See `docs/installer/PLAN.md` §7 for the design.
|
||||
|
||||
## Where they live: the `bundles` branch
|
||||
|
||||
**The JSON documents are not in this directory.** They are published to a branch of their own,
|
||||
[`bundles`](https://gitea.whitlocktech.com/RunicGateway/installer/src/branch/bundles), at its root:
|
||||
## Layout
|
||||
|
||||
| File | What it is |
|
||||
|---|---|
|
||||
@@ -27,24 +24,14 @@ Tags are UTC dates — `2026.08.04`. A second bundle on the same day (a sidecar
|
||||
morning, an overlay release in the afternoon) becomes `2026.08.04.2`, so one tag always names
|
||||
exactly one matrix.
|
||||
|
||||
**Why a branch rather than `main`.** `main` is protected and this job is unattended: the pre-receive
|
||||
hook declines a push from CI, which is not something a nightly cron can resolve. A branch of its own
|
||||
keeps everything the original choice was for — a reviewable diff, a git history of the compat
|
||||
matrix, plain anonymous raw URLs, no credentials on the shard host — and needs no protection
|
||||
exception. Whitelisting a scheduled job for pushes to the default branch would buy nothing this does
|
||||
not.
|
||||
|
||||
This directory keeps the documentation, because that is what belongs on `main`: the branch carries
|
||||
data, and only data.
|
||||
|
||||
## How the installer fetches these
|
||||
|
||||
Plain anonymous `GET`s against a public repo. The shard host gets no git and no Gitea credentials
|
||||
(`PLAN.md` §1), so nothing here may require auth:
|
||||
|
||||
```
|
||||
https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/bundles/current.json
|
||||
https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/bundles/bundle-2026.08.04.json
|
||||
https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/main/bundles/current.json
|
||||
https://gitea.whitlocktech.com/RunicGateway/installer/raw/branch/main/bundles/bundle-2026.08.04.json
|
||||
```
|
||||
|
||||
Bundles are committed rather than published as Gitea releases because this repo's *own* releases are
|
||||
@@ -71,8 +58,9 @@ protocol) or to either component's release version. All three move independently
|
||||
"protocol": 3,
|
||||
"assets": { // per-platform: the installer runs on each
|
||||
"linux-x86_64": { "name": "…", "url": "…", "sha256": "…" },
|
||||
"linux-aarch64": { "name": "…", "url": "…", "sha256": "…" },
|
||||
"windows-x86_64": { "name": "…", "url": "…", "sha256": "…" }
|
||||
// "linux-aarch64" joins these from link's first release built for it;
|
||||
// bundle.yml already knows the name (PLAN.md §5.2)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
40
bundles/bundle-2026.08.04.json
Normal file
40
bundles/bundle-2026.08.04.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"bundle": "2026.08.04",
|
||||
"generated": "2026-08-04T16:07:13Z",
|
||||
"protocol": 3,
|
||||
"link": {
|
||||
"repo": "RunicGateway/link",
|
||||
"tag": "v1.1.0",
|
||||
"version": "1.1.0",
|
||||
"protocol": 3,
|
||||
"assets": {
|
||||
"linux-x86_64": {
|
||||
"name": "uo-link-sidecar-linux-x86_64",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/link/releases/download/v1.1.0/uo-link-sidecar-linux-x86_64",
|
||||
"sha256": "27d491efda3fc6859dd38da9b2aa3b97b5fdf1dc5fc488a8916bb88b03443ad9"
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"name": "uo-link-sidecar-windows-x86_64.exe",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/link/releases/download/v1.1.0/uo-link-sidecar-windows-x86_64.exe",
|
||||
"sha256": "fbefd886af0355bf128f1f4c65657b772a58b128d32438061adb0069978e0b8f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overlay": {
|
||||
"repo": "RunicGateway/servuo-plugins",
|
||||
"tag": "v0.1.1",
|
||||
"version": "0.1.1",
|
||||
"commit": "3a52abbd77047e7c94883934533edcfef3ede555",
|
||||
"protocol": 3,
|
||||
"servuo": {
|
||||
"min_version": "57.4",
|
||||
"patches_verified_against": "57.4"
|
||||
},
|
||||
"asset": {
|
||||
"name": "runicgateway-overlay-0.1.1.tar.gz",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/servuo-plugins/releases/download/v0.1.1/runicgateway-overlay-0.1.1.tar.gz",
|
||||
"sha256": "75dc6d6ce08322b753a30303b3b2df6f15cf1e84658507d97430af44ec4d34d7"
|
||||
}
|
||||
}
|
||||
}
|
||||
40
bundles/current.json
Normal file
40
bundles/current.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"bundle": "2026.08.04",
|
||||
"generated": "2026-08-04T16:07:13Z",
|
||||
"protocol": 3,
|
||||
"link": {
|
||||
"repo": "RunicGateway/link",
|
||||
"tag": "v1.1.0",
|
||||
"version": "1.1.0",
|
||||
"protocol": 3,
|
||||
"assets": {
|
||||
"linux-x86_64": {
|
||||
"name": "uo-link-sidecar-linux-x86_64",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/link/releases/download/v1.1.0/uo-link-sidecar-linux-x86_64",
|
||||
"sha256": "27d491efda3fc6859dd38da9b2aa3b97b5fdf1dc5fc488a8916bb88b03443ad9"
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"name": "uo-link-sidecar-windows-x86_64.exe",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/link/releases/download/v1.1.0/uo-link-sidecar-windows-x86_64.exe",
|
||||
"sha256": "fbefd886af0355bf128f1f4c65657b772a58b128d32438061adb0069978e0b8f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overlay": {
|
||||
"repo": "RunicGateway/servuo-plugins",
|
||||
"tag": "v0.1.1",
|
||||
"version": "0.1.1",
|
||||
"commit": "3a52abbd77047e7c94883934533edcfef3ede555",
|
||||
"protocol": 3,
|
||||
"servuo": {
|
||||
"min_version": "57.4",
|
||||
"patches_verified_against": "57.4"
|
||||
},
|
||||
"asset": {
|
||||
"name": "runicgateway-overlay-0.1.1.tar.gz",
|
||||
"url": "https://gitea.whitlocktech.com/RunicGateway/servuo-plugins/releases/download/v0.1.1/runicgateway-overlay-0.1.1.tar.gz",
|
||||
"sha256": "75dc6d6ce08322b753a30303b3b2df6f15cf1e84658507d97430af44ec4d34d7"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user