From eec40f8786bdb18a3e1208be3f81d8e9b7febe9f Mon Sep 17 00:00:00 2001 From: anandpant Date: Sat, 1 Aug 2026 22:44:40 -0500 Subject: [PATCH] feat: publish verified public Tabex binaries --- .github/workflows/publish-tabex-release.yml | 40 +++++ .github/workflows/version-bumps.yml | 4 + README.md | 14 +- docs/setup.md | 10 +- scripts/publish-tabex-release.sh | 158 ++++++++++++++++++++ scripts/publish-tabex-release.test.sh | 103 +++++++++++++ scripts/update-packages.sh | 3 +- scripts/update-tabex-bin.sh | 53 +++++-- scripts/update-tabex-bin.test.sh | 67 +++++++++ scripts/validate-packages.sh | 4 + 10 files changed, 431 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/publish-tabex-release.yml create mode 100755 scripts/publish-tabex-release.sh create mode 100755 scripts/publish-tabex-release.test.sh create mode 100755 scripts/update-tabex-bin.test.sh diff --git a/.github/workflows/publish-tabex-release.yml b/.github/workflows/publish-tabex-release.yml new file mode 100644 index 0000000..61cd39d --- /dev/null +++ b/.github/workflows/publish-tabex-release.yml @@ -0,0 +1,40 @@ +name: publish-tabex-release + +on: + workflow_dispatch: + inputs: + release_tag: + description: Exact stable private Tabex release tag to mirror (for example v0.0.12) + required: true + type: string + +permissions: + actions: write + contents: write + +concurrency: + group: publish-tabex-release + cancel-in-progress: false + +jobs: + publish: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Checkout trusted publisher + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: main + + - name: Publish verified public binary assets + env: + RELEASE_TAG: ${{ inputs.release_tag }} + SOURCE_GITHUB_TOKEN: ${{ secrets.SHPIT_GH_TOKEN }} + TARGET_GITHUB_TOKEN: ${{ github.token }} + TARGET_REPOSITORY: ${{ github.repository }} + run: ./scripts/publish-tabex-release.sh "${RELEASE_TAG}" + + - name: Trigger pkgbuilds metadata bump + env: + GH_TOKEN: ${{ github.token }} + run: gh workflow run version-bumps.yml --repo "${{ github.repository }}" --ref main diff --git a/.github/workflows/version-bumps.yml b/.github/workflows/version-bumps.yml index bec61d8..88345b7 100644 --- a/.github/workflows/version-bumps.yml +++ b/.github/workflows/version-bumps.yml @@ -16,6 +16,10 @@ permissions: contents: write pull-requests: write +concurrency: + group: version-bumps + cancel-in-progress: false + jobs: update: runs-on: ubuntu-latest diff --git a/README.md b/README.md index d1021ea..67e55af 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ Arch Linux package definitions for SHPIT-maintained command-line tools. | Package | Upstream | Notes | |---|---|---| | `foundry-cli-bin` | `shpitdev/foundry-cli` GitHub Releases | Private release assets. Same auth model as the other SHPIT packages. | -| `meshix-cli-bin` | `shpitdev/meshix-observability` GitHub Releases | Private release assets. Same auth model as `tabex-bin` and `osyrra-bin`. | -| `tabex-bin` | `shpitdev/tabex` GitHub Releases | Private release assets. The PKGBUILD is public, but `makepkg` needs GitHub access to the `shpitdev` org to download the release tarball. | -| `osyrra-bin` | `shpitdev/osyrra` GitHub Releases | Private release assets. Same auth model as `tabex-bin`. | +| `meshix-cli-bin` | `shpitdev/meshix-observability` GitHub Releases | Private release assets. Same auth model as `osyrra-bin`. | +| `tabex-bin` | `shpitdev/pkgbuilds` GitHub Releases | Public binary release assets mirrored from the private Tabex release after digest and archive verification. No GitHub credentials are required to install a mirrored version. | +| `osyrra-bin` | `shpitdev/osyrra` GitHub Releases | Private release assets. Same auth model as `meshix-cli-bin`. | ## Automation @@ -38,7 +38,7 @@ cd makepkg -si ``` -`gh auth login` must be configured with access to the `shpitdev` org before `makepkg` can download the private `foundry-cli-bin`, `meshix-cli-bin`, `tabex-bin`, or `osyrra-bin` release assets. +`gh auth login` must be configured with access to the `shpitdev` org before `makepkg` can download the private `foundry-cli-bin`, `meshix-cli-bin`, or `osyrra-bin` release assets. Tabex versions published through the public binary channel need no GitHub credentials. After installing `tabex-bin`, start with: @@ -52,12 +52,12 @@ The package includes an install hook that prints the same guidance after install - You can use this repo immediately without creating the AUR repositories or AUR secrets. - The scheduled/manual bump workflow uses the repository `GITHUB_TOKEN` for branch and PR operations in this repo. -- Without `SHPIT_GH_TOKEN`, the workflow skips the private package updates (`foundry-cli-bin`, `meshix-cli-bin`, `tabex-bin`, and `osyrra-bin`). +- Without `SHPIT_GH_TOKEN`, the workflow skips the private package updates (`foundry-cli-bin`, `meshix-cli-bin`, and `osyrra-bin`). Public Tabex package updates remain available. - Without AUR secrets, the publish workflow exits successfully without pushing anywhere. ## Secrets -- `SHPIT_GH_TOKEN` — optional; required for GitHub Actions to refresh the private SHPIT packages (`foundry-cli-bin`, `meshix-cli-bin`, `tabex-bin`, and `osyrra-bin`) from their GitHub releases. +- `SHPIT_GH_TOKEN` — optional for routine version bumps; required by the trusted `publish-tabex-release` workflow only to read an exact stable release from the private Tabex repository. The workflow uses its repository-scoped token to trigger the local package bump only after the public mirror verifies. The secret is also required to refresh the other private SHPIT packages. - `AUR_USERNAME`, `AUR_EMAIL`, `AUR_SSH_PRIVATE_KEY` — optional until you actually want to publish to AUR. ## Local Auth @@ -76,7 +76,7 @@ The package includes an install hook that prints the same guidance after install 1. Create the GitHub repository and enable Actions. 2. In `Settings -> Actions -> General`, set workflow permissions to read and write, and enable GitHub Actions to create pull requests. -3. Attach the `SHPIT_GH_TOKEN` secret (org-level or repo-level) to this repo so the bump workflow can read the private release assets. +3. Attach the `SHPIT_GH_TOKEN` secret (org-level or repo-level) to this repo so the Tabex publisher and private-package bump paths can read their private release assets. 4. When the AUR repos exist, add `AUR_USERNAME`, `AUR_EMAIL`, and `AUR_SSH_PRIVATE_KEY`. 5. Run `version-bumps` manually once, confirm the PR output, then merge. 6. After the first merge, `publish.yml` will start pushing package updates to AUR only if those AUR secrets are present. diff --git a/docs/setup.md b/docs/setup.md index f7555c2..799f236 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -10,15 +10,17 @@ Use this first. - set workflow permissions to `Read and write` - enable `Allow GitHub Actions to create and approve pull requests` 4. Do not add any AUR secrets yet. -5. Attach `SHPIT_GH_TOKEN` if you want Actions to bump the private SHPIT packages. +5. Attach `SHPIT_GH_TOKEN` if you want Actions to bump private SHPIT packages or publish verified Tabex binaries from the private source release. 6. Run the `version-bumps` workflow manually. Result: - branch and PR creation use the repo `GITHUB_TOKEN` -- `meshix-cli-bin`, `tabex-bin`, and `osyrra-bin` update only if the repo has access to `SHPIT_GH_TOKEN` +- `meshix-cli-bin` and `osyrra-bin` update only if the repo has access to `SHPIT_GH_TOKEN` +- `tabex-bin` updates anonymously after an exact stable Tabex release has been mirrored publicly - AUR publishing is skipped without failing -- upstream `meshix-observability`, `tabex`, and `osyrra` release workflows can also trigger this workflow automatically with `gh workflow run version-bumps.yml`, but that depends on `SHPIT_WORKFLOW_DISPATCH_TOKEN` being available in their producer-repo Depot CI secrets +- upstream `meshix-observability` and `osyrra` release workflows can trigger the version-bump workflow directly +- the Tabex release workflow instead dispatches `publish-tabex-release.yml`; that trusted workflow verifies and publishes the exact public mirror before it triggers the local version bump ## GitHub UI Links @@ -28,7 +30,7 @@ Result: ## SHPIT_GH_TOKEN -Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/meshix-observability`, `shpitdev/tabex`, and `shpitdev/osyrra`. An org-level secret with `selected` visibility is the cleanest option if you have multiple consuming repos. +Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/meshix-observability`, `shpitdev/tabex`, and `shpitdev/osyrra`. The Tabex publisher uses it only for the private source read; publication and the same-repository bump dispatch use the workflow's repository-scoped token. An org-level secret with `selected` visibility is the cleanest option if you have multiple consuming repos. Attach it to this repo with: diff --git a/scripts/publish-tabex-release.sh b/scripts/publish-tabex-release.sh new file mode 100755 index 0000000..72946ec --- /dev/null +++ b/scripts/publish-tabex-release.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +set -euo pipefail + +if (($# != 1)); then + echo "usage: $0 " >&2 + exit 1 +fi + +release_tag="$1" +source_repo="shpitdev/tabex" +target_repo="${TARGET_REPOSITORY:-shpitdev/pkgbuilds}" + +if [[ ! "${release_tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Refusing to publish a non-stable Tabex release tag: ${release_tag}" >&2 + exit 1 +fi +if [[ -z "${SOURCE_GITHUB_TOKEN:-}" ]]; then + echo "SOURCE_GITHUB_TOKEN is required to read the private Tabex release." >&2 + exit 1 +fi +if [[ -z "${TARGET_GITHUB_TOKEN:-}" ]]; then + echo "TARGET_GITHUB_TOKEN is required to publish the public binary release." >&2 + exit 1 +fi + +version="${release_tag#v}" +public_tag="tabex-${release_tag}" +assets=( + "tabex_${release_tag}_darwin_arm64.tar.gz" + "tabex_${release_tag}_linux_amd64.tar.gz" +) +expected_names_json="$(printf '%s\n' "${assets[@]}" | jq -R . | jq -s .)" +workdir="$(mktemp -d)" +trap 'rm -rf "${workdir}"' EXIT + +verify_public_release() { + local public_release_file="$1" + local asset + local public_digest + local source_digest + + if ! jq -e --arg public_tag "${public_tag}" --argjson expected_names "${expected_names_json}" ' + .tag_name == $public_tag + and .draft == false + and .prerelease == false + and ([.assets[].name] | sort) == ($expected_names | sort) + and all(.assets[]; (.digest // "") | test("^sha256:[0-9a-f]{64}$")) + ' "${public_release_file}" >/dev/null; then + echo "Public release ${public_tag} is incomplete or contains unexpected assets." >&2 + return 1 + fi + + for asset in "${assets[@]}"; do + source_digest="$(jq -r --arg name "${asset}" '.assets[] | select(.name == $name) | .digest' "${source_release}")" + public_digest="$(jq -r --arg name "${asset}" '.assets[] | select(.name == $name) | .digest' "${public_release_file}")" + if [[ "${public_digest}" != "${source_digest}" ]]; then + echo "Public release ${public_tag} differs from the private source asset ${asset}." >&2 + return 1 + fi + done +} + +source_release="${workdir}/source-release.json" +GH_TOKEN="${SOURCE_GITHUB_TOKEN}" gh api \ + "repos/${source_repo}/releases/tags/${release_tag}" > "${source_release}" + +if ! jq -e --arg tag "${release_tag}" ' + .tag_name == $tag and .draft == false and .prerelease == false +' "${source_release}" >/dev/null; then + echo "The source must be an exact, published, stable Tabex release: ${release_tag}" >&2 + exit 1 +fi + +for asset in "${assets[@]}"; do + digest="$(jq -r --arg name "${asset}" ' + [.assets[] | select(.name == $name)] as $matches + | if ($matches | length) == 1 then $matches[0].digest // empty else empty end + ' "${source_release}")" + if [[ ! "${digest}" =~ ^sha256:[0-9a-f]{64}$ ]]; then + echo "The source release must contain one digested asset named ${asset}." >&2 + exit 1 + fi + + GH_TOKEN="${SOURCE_GITHUB_TOKEN}" gh release download "${release_tag}" \ + --repo "${source_repo}" \ + --pattern "${asset}" \ + --dir "${workdir}" >/dev/null + + actual_digest="$(sha256sum "${workdir}/${asset}" | awk '{print $1}')" + if [[ "sha256:${actual_digest}" != "${digest}" ]]; then + echo "SHA-256 mismatch for private release asset ${asset}." >&2 + exit 1 + fi + + archive_root="${asset%.tar.gz}" + archive_entries="$(tar -tzf "${workdir}/${asset}")" + expected_entries="${archive_root}/ +${archive_root}/tabex" + if [[ "${archive_entries}" != "${expected_entries}" ]]; then + echo "Unexpected archive contents in ${asset}; refusing to publish." >&2 + exit 1 + fi + + binary_entry_type="$(tar -tvzf "${workdir}/${asset}" | awk -v path="${archive_root}/tabex" '$NF == path { print substr($1, 1, 1) }')" + if [[ "${binary_entry_type}" != "-" ]]; then + echo "The Tabex entry in ${asset} is not a regular file; refusing to publish." >&2 + exit 1 + fi + + extract_dir="${workdir}/extract-${asset}" + mkdir -p "${extract_dir}" + tar -xzf "${workdir}/${asset}" -C "${extract_dir}" + if [[ ! -f "${extract_dir}/${archive_root}/tabex" || ! -x "${extract_dir}/${archive_root}/tabex" ]]; then + echo "The Tabex binary in ${asset} is not executable; refusing to publish." >&2 + exit 1 + fi +done + +public_release="${workdir}/public-release.json" +public_release_error="${workdir}/public-release.error" +if GH_TOKEN="${TARGET_GITHUB_TOKEN}" gh api \ + "repos/${target_repo}/releases/tags/${public_tag}" \ + > "${public_release}" 2> "${public_release_error}"; then + verify_public_release "${public_release}" + echo "Public Tabex binaries already match ${release_tag}; nothing to publish." + exit 0 +fi + +if ! grep -q 'HTTP 404' "${public_release_error}"; then + cat "${public_release_error}" >&2 + exit 1 +fi + +notes_file="${workdir}/release-notes.md" +cat > "${notes_file}" < "${public_release}" +verify_public_release "${public_release}" + +echo "Published ${target_repo} release ${public_tag}." diff --git a/scripts/publish-tabex-release.test.sh b/scripts/publish-tabex-release.test.sh new file mode 100755 index 0000000..5c7503b --- /dev/null +++ b/scripts/publish-tabex-release.test.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +workdir="$(mktemp -d)" +trap 'rm -rf "${workdir}"' EXIT +mkdir -p "${workdir}/bin" "${workdir}/assets" + +release_tag="v9.8.7" +for platform in darwin_arm64 linux_amd64; do + archive_root="tabex_${release_tag}_${platform}" + mkdir -p "${workdir}/stage/${archive_root}" + printf '#!/usr/bin/env bash\n' > "${workdir}/stage/${archive_root}/tabex" + chmod +x "${workdir}/stage/${archive_root}/tabex" + tar -czf "${workdir}/assets/${archive_root}.tar.gz" -C "${workdir}/stage" "${archive_root}" +done + +darwin_sha="$(sha256sum "${workdir}/assets/tabex_${release_tag}_darwin_arm64.tar.gz" | awk '{print $1}')" +linux_sha="$(sha256sum "${workdir}/assets/tabex_${release_tag}_linux_amd64.tar.gz" | awk '{print $1}')" +jq -n \ + --arg tag "${release_tag}" \ + --arg darwin_sha "${darwin_sha}" \ + --arg linux_sha "${linux_sha}" \ + '{ + tag_name: $tag, + draft: false, + prerelease: false, + assets: [ + {name: ("tabex_" + $tag + "_darwin_arm64.tar.gz"), digest: ("sha256:" + $darwin_sha)}, + {name: ("tabex_" + $tag + "_linux_amd64.tar.gz"), digest: ("sha256:" + $linux_sha)} + ] + }' > "${workdir}/source-release.json" + +cat > "${workdir}/bin/gh" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +if [[ "$1" == "api" && "$2" == repos/shpitdev/tabex/releases/tags/* ]]; then + cat "${TABEX_SOURCE_RELEASE_FIXTURE}" + exit 0 +fi +if [[ "$1" == "api" && "$2" == repos/shpitdev/pkgbuilds/releases/tags/* ]]; then + if [[ -f "${TABEX_PUBLIC_RELEASE_MARKER}" ]]; then + jq '.tag_name = "tabex-v9.8.7"' "${TABEX_SOURCE_RELEASE_FIXTURE}" + exit 0 + fi + echo 'gh: Not Found (HTTP 404)' >&2 + exit 1 +fi +if [[ "$1" == "release" && "$2" == "download" ]]; then + asset="" + output_dir="" + while (($#)); do + case "$1" in + --pattern) + asset="$2" + shift 2 + ;; + --dir) + output_dir="$2" + shift 2 + ;; + *) + shift + ;; + esac + done + cp "${TABEX_SOURCE_ASSET_DIR}/${asset}" "${output_dir}/${asset}" + exit 0 +fi +if [[ "$1" == "release" && "$2" == "create" ]]; then + printf '%q ' "$@" > "${TABEX_CREATE_LOG}" + touch "${TABEX_PUBLIC_RELEASE_MARKER}" + exit 0 +fi + +echo "Unexpected gh invocation: $*" >&2 +exit 1 +EOF +chmod +x "${workdir}/bin/gh" + +if PATH="${workdir}/bin:${PATH}" \ + "${repo_root}/scripts/publish-tabex-release.sh" "v9.8.7-rc.1" >/dev/null 2>&1; then + echo "Publisher accepted a prerelease tag." >&2 + exit 1 +fi + +PATH="${workdir}/bin:${PATH}" \ + SOURCE_GITHUB_TOKEN=source-token \ + TARGET_GITHUB_TOKEN=target-token \ + TARGET_REPOSITORY=shpitdev/pkgbuilds \ + TABEX_SOURCE_RELEASE_FIXTURE="${workdir}/source-release.json" \ + TABEX_SOURCE_ASSET_DIR="${workdir}/assets" \ + TABEX_CREATE_LOG="${workdir}/create.log" \ + TABEX_PUBLIC_RELEASE_MARKER="${workdir}/public-release-created" \ + "${repo_root}/scripts/publish-tabex-release.sh" "${release_tag}" + +grep -Fq 'tabex-v9.8.7' "${workdir}/create.log" +grep -Fq -- '--latest=false' "${workdir}/create.log" +if grep -Fq -- '--clobber' "${workdir}/create.log"; then + echo "Publisher must not overwrite existing public assets." >&2 + exit 1 +fi diff --git a/scripts/update-packages.sh b/scripts/update-packages.sh index b795955..70e1792 100755 --- a/scripts/update-packages.sh +++ b/scripts/update-packages.sh @@ -8,9 +8,8 @@ if (($# == 0)); then fi if [[ "$1" == "auto" ]]; then - packages=(meshix-cli-bin foundry-cli-bin) + packages=(meshix-cli-bin foundry-cli-bin tabex-bin) if [[ -n "${SHPIT_GH_TOKEN:-}" || -z "${GITHUB_ACTIONS:-}" ]]; then - packages+=(tabex-bin) packages+=(osyrra-bin) fi elif [[ "$1" == "all" ]]; then diff --git a/scripts/update-tabex-bin.sh b/scripts/update-tabex-bin.sh index b4faaa2..1dc599f 100755 --- a/scripts/update-tabex-bin.sh +++ b/scripts/update-tabex-bin.sh @@ -16,25 +16,33 @@ fi repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" pkgbuild="${repo_root}/tabex-bin/PKGBUILD" -repo="shpitdev/tabex" +repo="shpitdev/pkgbuilds" -if [[ -n "${SHPIT_GH_TOKEN:-}" ]]; then - release_json="$(GH_TOKEN="${SHPIT_GH_TOKEN}" gh api "repos/${repo}/releases/latest")" -elif [[ -n "${GITHUB_ACTIONS:-}" ]]; then +releases_json="$(gh api --paginate "repos/${repo}/releases?per_page=100" --slurp)" +release_json="$(jq -c ' + [ + .[][] + | select(.draft == false and .prerelease == false) + | select(.tag_name | test("^tabex-v[0-9]+\\.[0-9]+\\.[0-9]+$")) + ] + | sort_by(.tag_name | sub("^tabex-v"; "") | split(".") | map(tonumber)) + | last // empty +' <<<"${releases_json}")" + +if [[ -z "${release_json}" ]]; then if [[ "${optional}" == "true" ]]; then - echo "Skipping tabex-bin: SHPIT_GH_TOKEN is not configured in GitHub Actions." >&2 + echo "Skipping tabex-bin: no public stable Tabex binary release exists yet." >&2 exit 0 fi - echo "SHPIT_GH_TOKEN is required in GitHub Actions to read the private tabex release." >&2 + echo "No public stable Tabex binary release exists in ${repo}." >&2 exit 1 -else - release_json="$(gh api "repos/${repo}/releases/latest")" fi -pkgver="$(jq -r '.tag_name | ltrimstr("v")' <<<"${release_json}")" +public_tag="$(jq -r '.tag_name' <<<"${release_json}")" +pkgver="${public_tag#tabex-v}" asset_json="$(jq -c ' .assets - | map(select(.name | test("_linux_amd64\\.tar\\.gz$"))) + | map(select(.name == "tabex_v'"${pkgver}"'_linux_amd64.tar.gz")) | first ' <<<"${release_json}")" release_asset="$(jq -r '.name // empty' <<<"${asset_json}")" @@ -60,7 +68,28 @@ fi sha256="${sha256#sha256:}" -perl -0pi -e "s/^pkgver=.*/pkgver=${pkgver}/m" "${pkgbuild}" -perl -0pi -e "s/^_sha256=.*/_sha256='${sha256}'/m" "${pkgbuild}" +cat > "${pkgbuild}" < "${workdir}/release.json" <<'EOF' +[ + [ + { + "tag_name": "tabex-v9.8.6", + "draft": false, + "prerelease": false, + "assets": [] + }, + { + "tag_name": "tabex-v9.8.7", + "draft": false, + "prerelease": false, + "assets": [ + { + "name": "tabex_v9.8.7_linux_amd64.tar.gz", + "digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + ] + } + ] +] +EOF + +cat > "${workdir}/bin/gh" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +cat "${TABEX_RELEASE_FIXTURE}" +EOF + +cat > "${workdir}/bin/makepkg" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail +cat <<'SRCINFO' +pkgbase = tabex-bin + pkgver = 9.8.7 + source = https://github.com/shpitdev/pkgbuilds/releases/download/tabex-v9.8.7/tabex_v9.8.7_linux_amd64.tar.gz + sha256sums = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +pkgname = tabex-bin +SRCINFO +EOF + +chmod +x "${workdir}/bin/gh" "${workdir}/bin/makepkg" + +PATH="${workdir}/bin:${PATH}" \ + TABEX_RELEASE_FIXTURE="${workdir}/release.json" \ + "${workdir}/repo/scripts/update-tabex-bin.sh" + +pkgbuild="${workdir}/repo/tabex-bin/PKGBUILD" +grep -Fq 'pkgver=9.8.7' "${pkgbuild}" +grep -Fq 'source=("https://github.com/shpitdev/pkgbuilds/releases/download/tabex-v${pkgver}/${_asset}")' "${pkgbuild}" +grep -Fq "sha256sums=('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')" "${pkgbuild}" +if grep -Eq 'github-cli|gh release download|shpitdev/tabex/releases' "${pkgbuild}"; then + echo "Generated Tabex PKGBUILD still requires private GitHub access." >&2 + exit 1 +fi diff --git a/scripts/validate-packages.sh b/scripts/validate-packages.sh index ad1afcb..bd50a87 100755 --- a/scripts/validate-packages.sh +++ b/scripts/validate-packages.sh @@ -26,3 +26,7 @@ if [[ -f "${tabex_pkg}/PKGBUILD" ]]; then grep -q 'install="${pkgname}\.install"' "${tabex_pkg}/PKGBUILD" grep -q 'tabex setup' "${tabex_pkg}/tabex-bin.install" fi + +bash -n "${repo_root}/scripts/publish-tabex-release.sh" +"${repo_root}/scripts/publish-tabex-release.test.sh" +"${repo_root}/scripts/update-tabex-bin.test.sh"