diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 6ea1c7b..7ac7c7d 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: $SUDO apt-get update $SUDO apt-get install -y --no-install-recommends python3 python3-yaml dpkg-dev zstd - name: Full regression suite - run: ./tests/full-verify.sh + run: bash ./tests/full-verify.sh rpm-package: runs-on: ubuntu-latest @@ -37,8 +37,8 @@ jobs: - name: Build backend and RPM run: | set -euo pipefail - ./build.sh - ./packaging/build-rpm.sh + bash ./build.sh + bash ./packaging/build-rpm.sh VERSION="$(tr -d '[:space:]' < VERSION)" rpm -qpi "dist/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" @@ -52,7 +52,7 @@ jobs: run: pacman -Syu --noconfirm --needed git go zstd curl python - uses: actions/checkout@v4 - name: Build backend - run: ./build.sh + run: bash ./build.sh - name: Build pacman package as unprivileged user shell: bash run: | @@ -60,5 +60,5 @@ jobs: VERSION="$(tr -d '[:space:]' < VERSION)" useradd -m builder chown -R builder:builder "$WORKSPACE" - su builder -s /bin/bash -c "cd '$WORKSPACE' && ./packaging/build-arch.sh" + su builder -s /bin/bash -c "cd '$WORKSPACE' && bash ./packaging/build-arch.sh" test -s "dist/citizen-launcher-${VERSION}-1-x86_64.pkg.tar.zst" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2448404..2f9336a 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -32,7 +32,7 @@ jobs: run: | set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" - ./scripts/gitea-release.sh ensure \ + bash ./scripts/gitea-release.sh ensure \ "$TAG_NAME" \ "Citizen Launcher ${VERSION}" \ RELEASE_NOTES.md \ @@ -58,14 +58,14 @@ jobs: $SUDO apt-get update $SUDO apt-get install -y --no-install-recommends python3 python3-yaml dpkg-dev zstd curl - name: Full regression and package suite - run: ./tests/full-verify.sh + run: bash ./tests/full-verify.sh - name: Upload Debian and generic assets to Gitea shell: bash run: | set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" - ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher_${VERSION}_amd64.deb" - ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-linux-amd64.tar.gz" + bash ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher_${VERSION}_amd64.deb" + bash ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-linux-amd64.tar.gz" rpm: needs: prepare-release @@ -83,15 +83,15 @@ jobs: set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" test "$TAG_NAME" = "v${VERSION}" - ./build.sh - ./packaging/build-rpm.sh + bash ./build.sh + bash ./packaging/build-rpm.sh rpm -qpi "dist/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" - name: Upload RPM to Gitea shell: bash run: | set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" - ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" + bash ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" arch: needs: prepare-release @@ -110,17 +110,17 @@ jobs: set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" test "$TAG_NAME" = "v${VERSION}" - ./build.sh + bash ./build.sh useradd -m builder chown -R builder:builder "$WORKSPACE" - su builder -s /bin/bash -c "cd '$WORKSPACE' && CITIZEN_LAUNCHER_RELEASE_REPO='$CITIZEN_LAUNCHER_RELEASE_REPO' ./packaging/build-arch.sh" + su builder -s /bin/bash -c "cd '$WORKSPACE' && CITIZEN_LAUNCHER_RELEASE_REPO='$CITIZEN_LAUNCHER_RELEASE_REPO' bash ./packaging/build-arch.sh" test -s "dist/citizen-launcher-${VERSION}-1-x86_64.pkg.tar.zst" - name: Upload Arch package to Gitea shell: bash run: | set -euo pipefail VERSION="$(tr -d '[:space:]' < VERSION)" - ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-1-x86_64.pkg.tar.zst" + bash ./scripts/gitea-release.sh upload "$TAG_NAME" "dist/citizen-launcher-${VERSION}-1-x86_64.pkg.tar.zst" finalize-release: needs: [deb-and-generic, rpm, arch] @@ -132,7 +132,7 @@ jobs: run: | set -euo pipefail rm -rf release-assets - ./scripts/gitea-release.sh download-assets "$TAG_NAME" release-assets + bash ./scripts/gitea-release.sh download-assets "$TAG_NAME" release-assets VERSION="$(tr -d '[:space:]' < VERSION)" test -s "release-assets/citizen-launcher_${VERSION}_amd64.deb" test -s "release-assets/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" @@ -140,4 +140,4 @@ jobs: test -s "release-assets/citizen-launcher-${VERSION}-linux-amd64.tar.gz" (cd release-assets && sha256sum * | LC_ALL=C sort -k2 > SHA256SUMS.txt) - name: Publish SHA256SUMS on Gitea release - run: ./scripts/gitea-release.sh upload "$TAG_NAME" release-assets/SHA256SUMS.txt + run: bash ./scripts/gitea-release.sh upload "$TAG_NAME" release-assets/SHA256SUMS.txt diff --git a/GITEA.md b/GITEA.md index d826175..4d4c4cc 100644 --- a/GITEA.md +++ b/GITEA.md @@ -1,6 +1,6 @@ # Gitea Actions setup -Citizen Launcher 1.1.1 uses Gitea Actions natively. Workflows are in `.gitea/workflows/`; the old `.github/workflows/` directory is intentionally absent. +Citizen Launcher 1.1.2 uses Gitea Actions natively. Workflows are in `.gitea/workflows/`; the old `.github/workflows/` directory is intentionally absent. ## Requirements @@ -26,8 +26,8 @@ If your runner uses a different label, replace `runs-on: ubuntu-latest` in both Push a version tag matching `VERSION`, for example: ```bash -git tag v1.1.1 -git push origin v1.1.1 +git tag v1.1.2 +git push origin v1.1.2 ``` `.gitea/workflows/release.yml` then: diff --git a/INSTALLIEREN.sh b/INSTALLIEREN.sh index 60902cc..004368b 100644 --- a/INSTALLIEREN.sh +++ b/INSTALLIEREN.sh @@ -38,7 +38,7 @@ esac if $immutable; then echo "Immutable Linux-Variante erkannt ($id${variant:+/$variant})." echo "Citizen Launcher wird sicher im Benutzerkonto installiert; das Basis-Image bleibt unangetastet." - exec "$ROOT/install.sh" + exec bash "$ROOT/install.sh" fi case "$family" in @@ -80,4 +80,4 @@ esac echo "Kein passendes natives Paket im Projektordner gefunden." echo "Installiere die portable, vollständig updatefähige Benutzer-Version …" -exec "$ROOT/install.sh" +exec bash "$ROOT/install.sh" diff --git a/README.md b/README.md index fdf4898..8a1a145 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Citizen Launcher 1.1.1 +# Citizen Launcher 1.1.2 Citizen Launcher is a cross-distribution Star Citizen setup, launch, repair and maintenance application for Linux. The same static Go core runs on Debian/Ubuntu, Fedora/RHEL derivatives, Arch derivatives, openSUSE and generic glibc-based desktop Linux. Omarchy support is an optional integration, not a runtime requirement. @@ -8,7 +8,7 @@ Citizen Launcher is a cross-distribution Star Citizen setup, launch, repair and The launcher owns the fragile user-space gaming stack so users do not have to pick Wine builds, copy DXVK DLLs or rebuild prefixes by hand. Kernel, GPU driver, firmware and base-distribution upgrades remain owned by the Linux distribution. -The 1.0.1 gaming path was confirmed end-to-end on real hardware: launcher, RSI installation and Star Citizen playability. 1.1.1 keeps that gaming core and adds native multi-distribution packaging/update integration. +The 1.0.1 gaming path was confirmed end-to-end on real hardware: launcher, RSI installation and Star Citizen playability. 1.1.2 keeps that gaming core and adds native multi-distribution packaging/update integration. ## Supported Linux families @@ -32,25 +32,25 @@ The installer detects the distro family, prefers a native package found in `dist ### Debian / Ubuntu / Mint ```bash -sudo apt install ./dist/citizen-launcher_1.1.1_amd64.deb +sudo apt install ./dist/citizen-launcher_1.1.2_amd64.deb ``` ### Fedora / Nobara / RHEL family ```bash -sudo dnf install ./dist/citizen-launcher-1.1.1-1.linux.x86_64.rpm +sudo dnf install ./dist/citizen-launcher-1.1.2-1.linux.x86_64.rpm ``` ### openSUSE Tumbleweed / Slowroll ```bash -sudo zypper install ./dist/citizen-launcher-1.1.1-1.linux.x86_64.rpm +sudo zypper install ./dist/citizen-launcher-1.1.2-1.linux.x86_64.rpm ``` ### Arch / Manjaro / EndeavourOS / CachyOS / Omarchy ```bash -sudo pacman -U ./dist/citizen-launcher-1.1.1-1-x86_64.pkg.tar.zst +sudo pacman -U ./dist/citizen-launcher-1.1.2-1-x86_64.pkg.tar.zst ``` ### Generic / immutable desktop Linux diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 5746ac0..d5ab8d6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,8 +1,8 @@ -# Citizen Launcher 1.1.1 +# Citizen Launcher 1.1.2 ## Gitea-native CI/CD release -1.1.1 keeps the confirmed playable multi-distribution 1.1.x runtime and migrates the project automation from GitHub Actions to Gitea Actions. +1.1.2 keeps the confirmed playable multi-distribution 1.1.x runtime and hardens the Gitea Actions pipeline introduced in 1.1.1. ### Gitea workflows @@ -26,3 +26,10 @@ The release flow does not depend on cross-job `upload-artifact` compatibility. E ### Runtime Wine, DXVK, RSI Launcher setup, hardware checks, single-instance protection, repair, support bundles and the already confirmed playable Star Citizen path are unchanged. +## Gitea CI hardening + +- Gitea Actions invokes repository shell scripts explicitly through `bash`. +- Nested test, build and release scripts use the same mode-independent convention. +- Added a regression guard against direct `.sh` execution in the critical CI graph. +- Fixes Gitea/act exit code 126 (`Permission denied`) when checkout files are mode `0644`. + diff --git a/TEST_REPORT.md b/TEST_REPORT.md index 26855c2..246b3de 100644 --- a/TEST_REPORT.md +++ b/TEST_REPORT.md @@ -1,14 +1,14 @@ -# Citizen Launcher 1.1.1 – Verification Report +# Citizen Launcher 1.1.2 – Verification Report Date: 2026-09-01 ## Release scope -Citizen Launcher 1.1.1 keeps the confirmed playable 1.1.x multi-distribution gaming core and migrates CI/CD and release publishing to Gitea Actions. +Citizen Launcher 1.1.2 keeps the confirmed playable 1.1.x multi-distribution gaming core and hardens the Gitea-native CI/CD introduced in 1.1.1 against checkout permission differences. ## Automated release gate -The 1.1.1 tree passes the local release gate with: +The 1.1.2 tree passes the local release gate with: - shell syntax checks for installers, packaging, Gitea release helper and tests - `gofmt` cleanliness @@ -27,6 +27,8 @@ The 1.1.1 tree passes the local release gate with: - static validation of RPM spec and Arch PKGBUILD/package hooks - multi-distro platform-family and immutable-host regression tests - native package self-update parser/asset-selection tests for DEB, RPM and pacman formats +- full regression suite repeated successfully after forcing every repository `*.sh` file to mode `0644`; CI does not depend on executable bits +- regression guard rejects direct repository `.sh` execution in Gitea workflow entry points ## Gitea CI/CD design verified @@ -57,14 +59,18 @@ A separate build check confirmed that a `gitea:https://.../api/v1/repos/owner/re The current local build environment contains Debian packaging tools, therefore these artifacts can be built and inspected locally: -- `dist/citizen-launcher_1.1.1_amd64.deb` -- `dist/citizen-launcher-1.1.1-linux-amd64.tar.gz` +- `dist/citizen-launcher_1.1.2_amd64.deb` +- `dist/citizen-launcher-1.1.2-linux-amd64.tar.gz` The local environment does not provide native `rpmbuild` / Arch `makepkg`; the Gitea workflows build those in Fedora and Arch job containers: -- `citizen-launcher-1.1.1-1.linux.x86_64.rpm` -- `citizen-launcher-1.1.1-1-x86_64.pkg.tar.zst` +- `citizen-launcher-1.1.2-1.linux.x86_64.rpm` +- `citizen-launcher-1.1.2-1-x86_64.pkg.tar.zst` ## Gaming-core acceptance The Star Citizen install/play path is unchanged from the already accepted 1.0.1/1.1.0 line. The CI migration changes release and update plumbing, not Wine/DXVK/RSI launch behavior. + +## Checkout permission regression + +The complete `tests/full-verify.sh` suite was repeated after forcing every repository `*.sh` file to Unix mode `0644`. It still completed successfully. This reproduces the Gitea/act checkout condition that caused exit code 126 and verifies that CI/CD no longer depends on executable bits for repository shell scripts. Distributed archives still mark shell scripts executable for convenience. diff --git a/VERSION b/VERSION index 524cb55..45a1b3f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.1 +1.1.2 diff --git a/backend/bin/citizen-launcher b/backend/bin/citizen-launcher index 7bf37bf..61c091e 100644 Binary files a/backend/bin/citizen-launcher and b/backend/bin/citizen-launcher differ diff --git a/backend/cmd/citizen-launcher/main.go b/backend/cmd/citizen-launcher/main.go index e844bd5..1e29114 100644 --- a/backend/cmd/citizen-launcher/main.go +++ b/backend/cmd/citizen-launcher/main.go @@ -16,7 +16,7 @@ import ( ) var ( - appVersion = "1.1.1" + appVersion = "1.1.2" releaseRepo = "github:sendnwv/omarchy-sc" ) diff --git a/build.sh b/build.sh index 0190e9d..37c28dd 100644 --- a/build.sh +++ b/build.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -(cd "$ROOT/backend" && ./build.sh) +(cd "$ROOT/backend" && bash ./build.sh) echo "Build fertig: backend/bin/citizen-launcher" diff --git a/dist/citizen-launcher-1.1.2-linux-amd64.tar.gz b/dist/citizen-launcher-1.1.2-linux-amd64.tar.gz new file mode 100644 index 0000000..4112794 Binary files /dev/null and b/dist/citizen-launcher-1.1.2-linux-amd64.tar.gz differ diff --git a/dist/citizen-launcher_1.1.2_amd64.deb b/dist/citizen-launcher_1.1.2_amd64.deb new file mode 100644 index 0000000..e49f02e Binary files /dev/null and b/dist/citizen-launcher_1.1.2_amd64.deb differ diff --git a/install-omarchy.sh b/install-omarchy.sh index 2fc502b..87ec634 100644 --- a/install-omarchy.sh +++ b/install-omarchy.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -"$ROOT/install.sh" +bash "$ROOT/install.sh" command -v omarchy >/dev/null 2>&1 || { echo "Omarchy nicht gefunden; Standalone-Launcher ist trotzdem installiert."; exit 0; } DEST="$HOME/.config/omarchy/plugins/local.omarchy-citizen" mkdir -p "$DEST/backend/bin" diff --git a/integrations/omarchy/Panel.qml b/integrations/omarchy/Panel.qml index 38b4fc2..ca40c62 100644 --- a/integrations/omarchy/Panel.qml +++ b/integrations/omarchy/Panel.qml @@ -12,7 +12,7 @@ Panel { property var anchorItem: null property var hostWidget: null - property string pluginVersion: "1.1.1" + property string pluginVersion: "1.1.2" property string health: "checking" property string depsState: "checking" property string depsMissing: "" @@ -106,7 +106,7 @@ Panel { values[lines[i].slice(0, p)] = lines[i].slice(p + 1) } - pluginVersion = values.plugin_version || "1.1.1" + pluginVersion = values.plugin_version || "1.1.2" health = values.health || "setup" depsState = values.deps || "missing" depsMissing = values.deps_missing || "" diff --git a/integrations/omarchy/citizenctl b/integrations/omarchy/citizenctl index 3dc8529..d8805ef 100644 --- a/integrations/omarchy/citizenctl +++ b/integrations/omarchy/citizenctl @@ -2,7 +2,7 @@ set -u PLUGIN_ID="local.omarchy-citizen" -PLUGIN_VERSION="1.1.1" +PLUGIN_VERSION="1.1.2" XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" diff --git a/integrations/omarchy/manifest.json b/integrations/omarchy/manifest.json index 17e8353..f1a1c8d 100644 --- a/integrations/omarchy/manifest.json +++ b/integrations/omarchy/manifest.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "id": "local.omarchy-citizen", "name": "Citizen Launcher · Omarchy", - "version": "1.1.1", + "version": "1.1.2", "author": "Community prototype", "license": "MIT", "description": "Optional Omarchy bar integration for the distro-neutral Citizen Launcher.", diff --git a/packaging/build-all.sh b/packaging/build-all.sh index b7585e4..82d9f5c 100644 --- a/packaging/build-all.sh +++ b/packaging/build-all.sh @@ -1,16 +1,16 @@ #!/usr/bin/env bash set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" -"$ROOT/build.sh" -"$ROOT/packaging/build-deb.sh" -"$ROOT/packaging/build-tarball.sh" +bash "$ROOT/build.sh" +bash "$ROOT/packaging/build-deb.sh" +bash "$ROOT/packaging/build-tarball.sh" if command -v rpmbuild >/dev/null 2>&1; then - "$ROOT/packaging/build-rpm.sh" + bash "$ROOT/packaging/build-rpm.sh" else echo "Hinweis: rpmbuild fehlt – RPM wird in Fedora/openSUSE CI gebaut." >&2 fi if command -v makepkg >/dev/null 2>&1 && [[ $EUID -ne 0 ]]; then - "$ROOT/packaging/build-arch.sh" + bash "$ROOT/packaging/build-arch.sh" else echo "Hinweis: makepkg fehlt/Root – Arch-Paket wird in Arch CI gebaut." >&2 fi diff --git a/packaging/citizen-launcher.spec b/packaging/citizen-launcher.spec index 2551d74..ded0f8b 100644 --- a/packaging/citizen-launcher.spec +++ b/packaging/citizen-launcher.spec @@ -104,5 +104,7 @@ fi %config(noreplace) %{_sysconfdir}/citizen-launcher/release-repo %changelog +* Tue Sep 01 2026 Citizen Launcher Project - 1.1.2-1 +- Gitea Actions checkout permission hardening * Tue Sep 01 2026 Citizen Launcher Project - 1.1.1-1 - Multi-distribution native package support diff --git a/packaging/metainfo/io.github.citizenlauncher.CitizenLauncher.metainfo.xml b/packaging/metainfo/io.github.citizenlauncher.CitizenLauncher.metainfo.xml index c394248..b9417ae 100644 --- a/packaging/metainfo/io.github.citizenlauncher.CitizenLauncher.metainfo.xml +++ b/packaging/metainfo/io.github.citizenlauncher.CitizenLauncher.metainfo.xml @@ -13,6 +13,6 @@ https://github.com/sendnwv/omarchy-sc Game citizen-launcher - + diff --git a/packaging/rpm/citizen-launcher.spec b/packaging/rpm/citizen-launcher.spec index 2551d74..ded0f8b 100644 --- a/packaging/rpm/citizen-launcher.spec +++ b/packaging/rpm/citizen-launcher.spec @@ -104,5 +104,7 @@ fi %config(noreplace) %{_sysconfdir}/citizen-launcher/release-repo %changelog +* Tue Sep 01 2026 Citizen Launcher Project - 1.1.2-1 +- Gitea Actions checkout permission hardening * Tue Sep 01 2026 Citizen Launcher Project - 1.1.1-1 - Multi-distribution native package support diff --git a/tests/full-verify.sh b/tests/full-verify.sh index 6c27f8a..3fb7406 100644 --- a/tests/full-verify.sh +++ b/tests/full-verify.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash set -euo pipefail ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" -"$ROOT/tests/verify.sh" +bash "$ROOT/tests/verify.sh" +bash "$ROOT/tests/mode-independence.sh" (cd "$ROOT/backend" && go test -race ./...) -"$ROOT/backend/integration-test.sh" -"$ROOT/tests/gitea-release-helper.sh" -"$ROOT/tests/package-verify.sh" +bash "$ROOT/backend/integration-test.sh" +bash "$ROOT/tests/gitea-release-helper.sh" +bash "$ROOT/tests/package-verify.sh" echo 'Citizen Launcher full verification: OK' diff --git a/tests/gitea-release-helper.sh b/tests/gitea-release-helper.sh index 4cd6438..4edf9c2 100644 --- a/tests/gitea-release-helper.sh +++ b/tests/gitea-release-helper.sh @@ -25,7 +25,7 @@ class H(http.server.BaseHTTPRequestHandler): return r def do_GET(self): path=urllib.parse.urlparse(self.path).path - if path.endswith('/releases/tags/v1.1.1'): + if path.endswith('/releases/tags/v1.1.2'): if release is None: self.send_error(404); return self.sendj(200,self.rel()); return if path.startswith('/download/'): @@ -78,12 +78,12 @@ export GITEA_API_URL="http://127.0.0.1:${PORT}/api/v1" export GITEA_REPOSITORY="owner/repo" export GITEA_TOKEN="test-token" -echo first > "$TMP/citizen-launcher_1.1.1_amd64.deb" -"$ROOT/scripts/gitea-release.sh" ensure v1.1.1 'Citizen Launcher 1.1.1' "$ROOT/RELEASE_NOTES.md" deadbeef -"$ROOT/scripts/gitea-release.sh" ensure v1.1.1 'Citizen Launcher 1.1.1' "$ROOT/RELEASE_NOTES.md" deadbeef -"$ROOT/scripts/gitea-release.sh" upload v1.1.1 "$TMP/citizen-launcher_1.1.1_amd64.deb" -echo replacement > "$TMP/citizen-launcher_1.1.1_amd64.deb" -"$ROOT/scripts/gitea-release.sh" upload v1.1.1 "$TMP/citizen-launcher_1.1.1_amd64.deb" -"$ROOT/scripts/gitea-release.sh" download-assets v1.1.1 "$TMP/download" -cmp "$TMP/citizen-launcher_1.1.1_amd64.deb" "$TMP/download/citizen-launcher_1.1.1_amd64.deb" +echo first > "$TMP/citizen-launcher_1.1.2_amd64.deb" +bash "$ROOT/scripts/gitea-release.sh" ensure v1.1.2 'Citizen Launcher 1.1.2' "$ROOT/RELEASE_NOTES.md" deadbeef +bash "$ROOT/scripts/gitea-release.sh" ensure v1.1.2 'Citizen Launcher 1.1.2' "$ROOT/RELEASE_NOTES.md" deadbeef +bash "$ROOT/scripts/gitea-release.sh" upload v1.1.2 "$TMP/citizen-launcher_1.1.2_amd64.deb" +echo replacement > "$TMP/citizen-launcher_1.1.2_amd64.deb" +bash "$ROOT/scripts/gitea-release.sh" upload v1.1.2 "$TMP/citizen-launcher_1.1.2_amd64.deb" +bash "$ROOT/scripts/gitea-release.sh" download-assets v1.1.2 "$TMP/download" +cmp "$TMP/citizen-launcher_1.1.2_amd64.deb" "$TMP/download/citizen-launcher_1.1.2_amd64.deb" echo 'Gitea release helper verification: OK' diff --git a/tests/mode-independence.sh b/tests/mode-independence.sh new file mode 100644 index 0000000..eb9d290 --- /dev/null +++ b/tests/mode-independence.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" + +python3 - "$ROOT" <<'PY' +from pathlib import Path +import re, sys +root = Path(sys.argv[1]) +check = [ + root/'build.sh', root/'install-omarchy.sh', root/'INSTALLIEREN.sh', + root/'tests/full-verify.sh', root/'tests/verify.sh', root/'tests/package-verify.sh', + root/'tests/gitea-release-helper.sh', root/'packaging/build-all.sh', + root/'.gitea/workflows/ci.yml', root/'.gitea/workflows/release.yml', +] +for p in check: + text = p.read_text() + bad = [] + for lineno, line in enumerate(text.splitlines(), 1): + stripped = line.strip() + if stripped.startswith('#') or stripped.endswith('\\') or stripped.endswith('; do'): + continue + # Direct ./script.sh command (workflow or shell command) without an interpreter. + if re.search(r'(^|[;&|]\s*|run:\s*)\./[^\s"\x27]+\.sh(?:\s|$)', stripped): + bad.append((lineno, stripped)) + # Direct "$ROOT/path/script.sh" command at start of a shell line. + if re.search(r'^"?\$ROOT/[^"\s]+\.sh"?(?:\s|$)', stripped): + bad.append((lineno, stripped)) + if bad: + raise SystemExit(f'direct shell execution remains in {p}: {bad}') +print('Mode-independent shell invocation: OK') +PY diff --git a/tests/package-verify.sh b/tests/package-verify.sh index 2e63991..2f130f9 100644 --- a/tests/package-verify.sh +++ b/tests/package-verify.sh @@ -4,8 +4,8 @@ ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" VERSION="$(tr -d '[:space:]' < "$ROOT/VERSION")" rm -rf "$ROOT/dist" mkdir -p "$ROOT/dist" -"$ROOT/packaging/build-deb.sh" -"$ROOT/packaging/build-tarball.sh" +bash "$ROOT/packaging/build-deb.sh" +bash "$ROOT/packaging/build-tarball.sh" DEB="$ROOT/dist/citizen-launcher_${VERSION}_amd64.deb" TAR="$ROOT/dist/citizen-launcher-${VERSION}-linux-amd64.tar.gz" [[ -s "$DEB" && -s "$TAR" ]] @@ -45,14 +45,14 @@ grep -q "'x86_64'" "$ROOT/packaging/arch/PKGBUILD.in" grep -q 'citizen-launcher-self-update.timer' "$ROOT/packaging/arch/PKGBUILD.in" if command -v rpmbuild >/dev/null 2>&1; then - "$ROOT/packaging/build-rpm.sh" + bash "$ROOT/packaging/build-rpm.sh" RPM="$ROOT/dist/citizen-launcher-${VERSION}-1.linux.x86_64.rpm" [[ -s "$RPM" ]] rpm -qp --qf '%{NAME}\n%{VERSION}\n%{ARCH}\n' "$RPM" | grep -qx 'citizen-launcher' -m1 fi if command -v makepkg >/dev/null 2>&1 && [[ $EUID -ne 0 ]]; then - "$ROOT/packaging/build-arch.sh" + bash "$ROOT/packaging/build-arch.sh" [[ -s "$ROOT/dist/citizen-launcher-${VERSION}-1-x86_64.pkg.tar.zst" ]] fi diff --git a/tests/verify.sh b/tests/verify.sh index 5a6129b..f7f76de 100644 --- a/tests/verify.sh +++ b/tests/verify.sh @@ -5,11 +5,11 @@ for f in \ "$ROOT/install.sh" "$ROOT/uninstall.sh" "$ROOT/install-omarchy.sh" "$ROOT/INSTALLIEREN.sh" \ "$ROOT/build.sh" "$ROOT/packaging/build-deb.sh" "$ROOT/packaging/build-rpm.sh" \ "$ROOT/packaging/build-arch.sh" "$ROOT/packaging/build-tarball.sh" "$ROOT/packaging/build-all.sh" \ - "$ROOT/scripts/gitea-release.sh" "$ROOT/tests/gitea-release-helper.sh"; do + "$ROOT/scripts/gitea-release.sh" "$ROOT/tests/gitea-release-helper.sh" "$ROOT/tests/mode-independence.sh"; do bash -n "$f" done (cd "$ROOT/backend" && gofmt -w cmd/citizen-launcher && go test ./... && go vet ./...) -"$ROOT/build.sh" +bash "$ROOT/build.sh" [[ "$("$ROOT/backend/bin/citizen-launcher" --version)" == "$(tr -d '[:space:]' < "$ROOT/VERSION")" ]] [[ ! -n "$(gofmt -l "$ROOT/backend/cmd/citizen-launcher")" ]] python3 - <<'PY' "$ROOT" @@ -22,6 +22,12 @@ release=(root/'.gitea/workflows/release.yml').read_text() assert 'gh release' not in release assert 'gitea.api_url' in release and 'gitea.token' in release assert 'actions/upload-artifact' not in release and 'actions/download-artifact' not in release + +import re +for wf in [root/'.gitea/workflows/ci.yml', root/'.gitea/workflows/release.yml']: + text=wf.read_text() + bad=re.findall(r'(?m)^\s*(?:run:\s*)?(\./[^\s]+\.sh)(?:\s|$)', text) + assert not bad, f'workflow executes shell script directly: {wf}: {bad}' print('Gitea workflow yaml: OK') PY echo 'Citizen Launcher verification: OK'