diff --git a/.gitea/workflows/auto-tag.yml b/.gitea/workflows/auto-tag.yml index 7f4339a0..33eb5011 100644 --- a/.gitea/workflows/auto-tag.yml +++ b/.gitea/workflows/auto-tag.yml @@ -1,7 +1,7 @@ name: Auto Tag # Runs on every merge to master — reads the latest semver tag, increments -# the patch version, and pushes a new tag (which triggers release.yml). +# the patch version, pushes a new tag, then runs release builds in this workflow. on: push: @@ -41,7 +41,7 @@ jobs: echo "Latest tag: ${LATEST:-none} → Next: $NEXT" - # Create and push the tag via git so the tag push event triggers release.yml. + # Create and push the tag via git. git init git remote add origin "http://oauth2:${RELEASE_TOKEN}@172.0.0.29:3000/${GITHUB_REPOSITORY}.git" git fetch --depth=1 origin "$GITHUB_SHA" @@ -61,6 +61,7 @@ jobs: build-linux-amd64: needs: autotag + if: needs.autotag.result == 'success' runs-on: linux-amd64 container: image: rust:1.88-slim @@ -147,6 +148,7 @@ jobs: build-windows-amd64: needs: autotag + if: needs.autotag.result == 'success' runs-on: linux-amd64 container: image: rust:1.88-slim @@ -237,6 +239,7 @@ jobs: build-macos-arm64: needs: autotag + if: needs.autotag.result == 'success' runs-on: macos-arm64 steps: - name: Checkout @@ -323,6 +326,7 @@ jobs: build-linux-arm64: needs: autotag + if: needs.autotag.result == 'success' runs-on: linux-arm64 container: image: rust:1.88-slim diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml deleted file mode 100644 index 58521da7..00000000 --- a/.gitea/workflows/release.yml +++ /dev/null @@ -1,343 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v*' - -jobs: - build-linux-amd64: - runs-on: linux-amd64 - container: - image: rust:1.88-slim - steps: - - name: Checkout - run: | - apt-get update -qq && apt-get install -y -qq git - git init - git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git - git fetch --depth=1 origin $GITHUB_SHA - git checkout FETCH_HEAD - - name: Install dependencies - run: | - apt-get update -qq && apt-get install -y -qq \ - libwebkit2gtk-4.1-dev libssl-dev libgtk-3-dev \ - libayatana-appindicator3-dev librsvg2-dev patchelf \ - pkg-config curl perl jq - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - - apt-get install -y nodejs - - name: Build - run: | - npm ci --legacy-peer-deps - rustup target add x86_64-unknown-linux-gnu - cargo install tauri-cli --version "^2" --locked - CI=true cargo tauri build --target x86_64-unknown-linux-gnu - - name: Upload artifacts - env: - RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} - run: | - set -eu - API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY" - TAG="$GITHUB_REF_NAME" - echo "Creating release for $TAG..." - curl -sf -X POST "$API/releases" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"$TAG\",\"name\":\"TFTSR $TAG\",\"body\":\"Release $TAG\",\"draft\":false}" || true - RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \ - -H "Authorization: token $RELEASE_TOKEN" | jq -r '.id') - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then - echo "ERROR: Failed to get release ID for $TAG" - exit 1 - fi - echo "Release ID: $RELEASE_ID" - ARTIFACTS=$(find src-tauri/target/x86_64-unknown-linux-gnu/release/bundle -type f \ - \( -name "*.deb" -o -name "*.rpm" -o -name "*.AppImage" \)) - if [ -z "$ARTIFACTS" ]; then - echo "ERROR: No Linux amd64 artifacts were found to upload." - exit 1 - fi - printf '%s\n' "$ARTIFACTS" | while IFS= read -r f; do - NAME=$(basename "$f") - echo "Uploading $NAME..." - EXISTING_IDS=$(curl -sf "$API/releases/$RELEASE_ID" \ - -H "Authorization: token $RELEASE_TOKEN" \ - | jq -r --arg name "$NAME" '.assets[]? | select(.name == $name) | .id') - if [ -n "$EXISTING_IDS" ]; then - printf '%s\n' "$EXISTING_IDS" | while IFS= read -r id; do - [ -n "$id" ] || continue - echo "Deleting existing asset id=$id name=$NAME before upload..." - curl -sf -X DELETE "$API/releases/$RELEASE_ID/assets/$id" \ - -H "Authorization: token $RELEASE_TOKEN" - done - fi - RESP_FILE=$(mktemp) - HTTP_CODE=$(curl -sS -o "$RESP_FILE" -w "%{http_code}" -X POST "$API/releases/$RELEASE_ID/assets" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -F "attachment=@$f;filename=$NAME") - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✓ Uploaded $NAME" - else - echo "✗ Upload failed for $NAME (HTTP $HTTP_CODE)" - python - "$RESP_FILE" <<'PY' -import pathlib, sys -print(pathlib.Path(sys.argv[1]).read_text(errors="replace")[:2000]) -PY - exit 1 - fi - done - - build-windows-amd64: - runs-on: linux-amd64 - container: - image: rust:1.88-slim - steps: - - name: Checkout - run: | - apt-get update -qq && apt-get install -y -qq git - git init - git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git - git fetch --depth=1 origin $GITHUB_SHA - git checkout FETCH_HEAD - - name: Install dependencies - run: | - apt-get update -qq && apt-get install -y -qq mingw-w64 curl nsis perl make jq - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - - apt-get install -y nodejs - - name: Build - env: - CC_x86_64_pc_windows_gnu: x86_64-w64-mingw32-gcc - CXX_x86_64_pc_windows_gnu: x86_64-w64-mingw32-g++ - AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar - CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc - OPENSSL_NO_VENDOR: "0" - OPENSSL_STATIC: "1" - run: | - npm ci --legacy-peer-deps - rustup target add x86_64-pc-windows-gnu - cargo install tauri-cli --version "^2" --locked - CI=true cargo tauri build --target x86_64-pc-windows-gnu - - name: Upload artifacts - env: - RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} - run: | - set -eu - API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY" - TAG="$GITHUB_REF_NAME" - echo "Creating release for $TAG..." - curl -sf -X POST "$API/releases" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"$TAG\",\"name\":\"TFTSR $TAG\",\"body\":\"Release $TAG\",\"draft\":false}" || true - RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \ - -H "Authorization: token $RELEASE_TOKEN" | jq -r '.id') - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then - echo "ERROR: Failed to get release ID for $TAG" - exit 1 - fi - echo "Release ID: $RELEASE_ID" - ARTIFACTS=$(find src-tauri/target/x86_64-pc-windows-gnu/release/bundle -type f \ - \( -name "*.exe" -o -name "*.msi" \) 2>/dev/null) - if [ -z "$ARTIFACTS" ]; then - echo "ERROR: No Windows amd64 artifacts were found to upload." - exit 1 - fi - printf '%s\n' "$ARTIFACTS" | while IFS= read -r f; do - NAME=$(basename "$f") - echo "Uploading $NAME..." - EXISTING_IDS=$(curl -sf "$API/releases/$RELEASE_ID" \ - -H "Authorization: token $RELEASE_TOKEN" \ - | jq -r --arg name "$NAME" '.assets[]? | select(.name == $name) | .id') - if [ -n "$EXISTING_IDS" ]; then - printf '%s\n' "$EXISTING_IDS" | while IFS= read -r id; do - [ -n "$id" ] || continue - echo "Deleting existing asset id=$id name=$NAME before upload..." - curl -sf -X DELETE "$API/releases/$RELEASE_ID/assets/$id" \ - -H "Authorization: token $RELEASE_TOKEN" - done - fi - RESP_FILE=$(mktemp) - HTTP_CODE=$(curl -sS -o "$RESP_FILE" -w "%{http_code}" -X POST "$API/releases/$RELEASE_ID/assets" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -F "attachment=@$f;filename=$NAME") - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✓ Uploaded $NAME" - else - echo "✗ Upload failed for $NAME (HTTP $HTTP_CODE)" - python - "$RESP_FILE" <<'PY' -import pathlib, sys -print(pathlib.Path(sys.argv[1]).read_text(errors="replace")[:2000]) -PY - exit 1 - fi - done - - build-macos-arm64: - runs-on: macos-arm64 - steps: - - name: Checkout - run: | - git init - git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git - git fetch --depth=1 origin $GITHUB_SHA - git checkout FETCH_HEAD - - name: Build - env: - MACOSX_DEPLOYMENT_TARGET: "11.0" - run: | - npm ci --legacy-peer-deps - rustup target add aarch64-apple-darwin - cargo install tauri-cli --version "^2" --locked - # Build the .app bundle only (no DMG yet so we can sign before packaging) - CI=true cargo tauri build --target aarch64-apple-darwin --bundles app - APP=$(find src-tauri/target/aarch64-apple-darwin/release/bundle/macos -maxdepth 1 -type d -name "*.app" | head -n 1) - if [ -z "$APP" ]; then - echo "ERROR: Could not find macOS app bundle" - exit 1 - fi - APP_NAME=$(basename "$APP" .app) - # Ad-hoc sign: changes Gatekeeper error from "damaged" to "unidentified developer" - codesign --deep --force --sign - "$APP" - # Create DMG from the signed .app - mkdir -p src-tauri/target/aarch64-apple-darwin/release/bundle/dmg - DMG=src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/${APP_NAME}.dmg - hdiutil create -volname "$APP_NAME" -srcfolder "$APP" -ov -format UDZO "$DMG" - - name: Upload artifacts - env: - RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} - run: | - set -eu - API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY" - TAG="$GITHUB_REF_NAME" - # Create release (idempotent) - echo "Creating release for $TAG..." - curl -sf -X POST "$API/releases" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"$TAG\",\"name\":\"TFTSR $TAG\",\"body\":\"Release $TAG\",\"draft\":false}" || true - # Get release ID - RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \ - -H "Authorization: token $RELEASE_TOKEN" | jq -r '.id') - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then - echo "ERROR: Failed to get release ID for $TAG" - echo "Attempting to list recent releases..." - curl -sf "$API/releases" -H "Authorization: token $RELEASE_TOKEN" | jq -r '.[] | "\(.tag_name): \(.id)"' | head -5 - exit 1 - fi - echo "Release ID: $RELEASE_ID" - ARTIFACTS=$(find src-tauri/target/aarch64-apple-darwin/release/bundle -type f -name "*.dmg") - if [ -z "$ARTIFACTS" ]; then - echo "ERROR: No macOS arm64 DMG artifacts were found to upload." - exit 1 - fi - printf '%s\n' "$ARTIFACTS" | while IFS= read -r f; do - NAME=$(basename "$f") - echo "Uploading $NAME..." - EXISTING_IDS=$(curl -sf "$API/releases/$RELEASE_ID" \ - -H "Authorization: token $RELEASE_TOKEN" \ - | jq -r --arg name "$NAME" '.assets[]? | select(.name == $name) | .id') - if [ -n "$EXISTING_IDS" ]; then - printf '%s\n' "$EXISTING_IDS" | while IFS= read -r id; do - [ -n "$id" ] || continue - echo "Deleting existing asset id=$id name=$NAME before upload..." - curl -sf -X DELETE "$API/releases/$RELEASE_ID/assets/$id" \ - -H "Authorization: token $RELEASE_TOKEN" - done - fi - RESP_FILE=$(mktemp) - HTTP_CODE=$(curl -sS -o "$RESP_FILE" -w "%{http_code}" -X POST "$API/releases/$RELEASE_ID/assets" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -F "attachment=@$f;filename=$NAME") - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✓ Uploaded $NAME" - else - echo "✗ Upload failed for $NAME (HTTP $HTTP_CODE)" - python - "$RESP_FILE" <<'PY' -import pathlib, sys -print(pathlib.Path(sys.argv[1]).read_text(errors="replace")[:2000]) -PY - exit 1 - fi - done - - build-linux-arm64: - runs-on: linux-arm64 - container: - image: rust:1.88-slim - steps: - - name: Checkout - run: | - apt-get update -qq && apt-get install -y -qq git - git init - git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git - git fetch --depth=1 origin $GITHUB_SHA - git checkout FETCH_HEAD - - name: Install dependencies - run: | - # Native ARM64 build (no cross-compilation needed) - apt-get update -qq && apt-get install -y -qq \ - libwebkit2gtk-4.1-dev libssl-dev libgtk-3-dev \ - libayatana-appindicator3-dev librsvg2-dev patchelf \ - pkg-config curl perl jq - curl -fsSL https://deb.nodesource.com/setup_22.x | bash - - apt-get install -y nodejs - - name: Build - run: | - npm ci --legacy-peer-deps - cargo install tauri-cli --version "^2" --locked - # Native ARM64 build - no explicit target needed - CI=true cargo tauri build - - name: Upload artifacts - env: - RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} - run: | - set -eu - API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY" - TAG="$GITHUB_REF_NAME" - echo "Creating release for $TAG..." - curl -sf -X POST "$API/releases" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"$TAG\",\"name\":\"TFTSR $TAG\",\"body\":\"Release $TAG\",\"draft\":false}" || true - RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \ - -H "Authorization: token $RELEASE_TOKEN" | jq -r '.id') - if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then - echo "ERROR: Failed to get release ID for $TAG" - exit 1 - fi - echo "Release ID: $RELEASE_ID" - ARTIFACTS=$(find src-tauri/target/release/bundle -type f \ - \( -name "*.deb" -o -name "*.rpm" -o -name "*.AppImage" \)) - if [ -z "$ARTIFACTS" ]; then - echo "ERROR: No Linux arm64 artifacts were found to upload." - exit 1 - fi - printf '%s\n' "$ARTIFACTS" | while IFS= read -r f; do - NAME=$(basename "$f") - echo "Uploading $NAME..." - EXISTING_IDS=$(curl -sf "$API/releases/$RELEASE_ID" \ - -H "Authorization: token $RELEASE_TOKEN" \ - | jq -r --arg name "$NAME" '.assets[]? | select(.name == $name) | .id') - if [ -n "$EXISTING_IDS" ]; then - printf '%s\n' "$EXISTING_IDS" | while IFS= read -r id; do - [ -n "$id" ] || continue - echo "Deleting existing asset id=$id name=$NAME before upload..." - curl -sf -X DELETE "$API/releases/$RELEASE_ID/assets/$id" \ - -H "Authorization: token $RELEASE_TOKEN" - done - fi - RESP_FILE=$(mktemp) - HTTP_CODE=$(curl -sS -o "$RESP_FILE" -w "%{http_code}" -X POST "$API/releases/$RELEASE_ID/assets" \ - -H "Authorization: token $RELEASE_TOKEN" \ - -F "attachment=@$f;filename=$NAME") - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✓ Uploaded $NAME" - else - echo "✗ Upload failed for $NAME (HTTP $HTTP_CODE)" - python - "$RESP_FILE" <<'PY' -import pathlib, sys -print(pathlib.Path(sys.argv[1]).read_text(errors="replace")[:2000]) -PY - exit 1 - fi - done diff --git a/README.md b/README.md index 257832b1..a4930146 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ tftsr/ └── .gitea/ └── workflows/ ├── test.yml # CI: rustfmt · clippy · cargo test · tsc · vitest (every push/PR) - └── release.yml # Release: linux/amd64 + windows/amd64 + linux/arm64 → Gitea release + └── auto-tag.yml # Auto tag + release: linux/amd64 + windows/amd64 + linux/arm64 + macOS ``` --- @@ -251,7 +251,7 @@ The project uses **Gitea Actions** (act_runner v0.3.1) connected to the Gitea in | Workflow | Trigger | Jobs | |---|---|---| | `.gitea/workflows/test.yml` | Every push / PR | rustfmt · clippy · cargo test (64) · tsc · vitest (13) | -| `.gitea/workflows/release.yml` | Tag `v*` or manual dispatch | Build linux/amd64 + windows/amd64 + linux/arm64 → upload to Gitea release | +| `.gitea/workflows/auto-tag.yml` | Push to `master` | Auto-tag, then build linux/amd64 + windows/amd64 + linux/arm64 + macOS and upload assets | **Runners:** diff --git a/docs/wiki/CICD-Pipeline.md b/docs/wiki/CICD-Pipeline.md index 54ad3345..e36fd2da 100644 --- a/docs/wiki/CICD-Pipeline.md +++ b/docs/wiki/CICD-Pipeline.md @@ -65,16 +65,12 @@ steps: --- -## Release Pipeline (`.gitea/workflows/release.yml`) +## Release Pipeline (`.gitea/workflows/auto-tag.yml`) -**Triggers:** Git tags matching `v*` +**Triggers:** Pushes to `master` (auto-tag), then release build/upload jobs run after `autotag`. -Auto tags are created by `.gitea/workflows/auto-tag.yml` using `git tag` + `git push` -(not the tag API endpoint), so the tag push event reliably triggers this workflow. - -In addition, `.gitea/workflows/auto-tag.yml` now runs the same release build/upload -jobs after tagging (`needs: auto-tag`) to guarantee release execution even if the -separate tag-triggered workflow is not dispatched by the server. +Auto tags are created by `.gitea/workflows/auto-tag.yml` using `git tag` + `git push`. +Release jobs are executed in the same workflow and depend on `autotag` completion. ``` Jobs (run in parallel): @@ -113,7 +109,7 @@ the repo directly within its commands (using `http://172.0.0.29:3000`, accessibl the local machine) and uploads its artifacts inline. The `upload-release` step (amd64) handles amd64 + windows artifacts only. -**Clone override (release.yml — amd64 workspace):** +**Clone override (auto-tag.yml — amd64 workspace):** ```yaml clone: diff --git a/tests/unit/autoTagWorkflowTrigger.test.ts b/tests/unit/autoTagWorkflowTrigger.test.ts index 1984c6f8..e4dda6bc 100644 --- a/tests/unit/autoTagWorkflowTrigger.test.ts +++ b/tests/unit/autoTagWorkflowTrigger.test.ts @@ -23,6 +23,7 @@ describe("auto-tag workflow release triggering", () => { expect(workflow).toContain("build-macos-arm64:"); expect(workflow).toContain("build-linux-arm64:"); expect(workflow).toContain("needs: autotag"); + expect(workflow).toContain("if: needs.autotag.result == 'success'"); expect(workflow).toContain("TAG=$(curl -s \"$API/tags?limit=50\""); expect(workflow).toContain("ERROR: Could not resolve release tag from repository tags."); }); diff --git a/tests/unit/releaseWorkflowCrossPlatformArtifacts.test.ts b/tests/unit/releaseWorkflowCrossPlatformArtifacts.test.ts index a78225a9..9c5de48b 100644 --- a/tests/unit/releaseWorkflowCrossPlatformArtifacts.test.ts +++ b/tests/unit/releaseWorkflowCrossPlatformArtifacts.test.ts @@ -2,28 +2,28 @@ import { describe, expect, it } from "vitest"; import { readFileSync } from "node:fs"; import path from "node:path"; -const releaseWorkflowPath = path.resolve( +const autoTagWorkflowPath = path.resolve( process.cwd(), - ".gitea/workflows/release.yml", + ".gitea/workflows/auto-tag.yml", ); -describe("release workflow cross-platform artifact handling", () => { +describe("auto-tag release cross-platform artifact handling", () => { it("overrides OpenSSL vendoring for windows-gnu cross builds", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).toContain("OPENSSL_NO_VENDOR: \"0\""); expect(workflow).toContain("OPENSSL_STATIC: \"1\""); }); it("fails linux uploads when no artifacts are found", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).toContain("ERROR: No Linux amd64 artifacts were found to upload."); expect(workflow).toContain("ERROR: No Linux arm64 artifacts were found to upload."); }); it("fails windows uploads when no artifacts are found", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).toContain( "ERROR: No Windows amd64 artifacts were found to upload.", @@ -31,7 +31,7 @@ describe("release workflow cross-platform artifact handling", () => { }); it("replaces existing release assets before uploading reruns", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).toContain("Deleting existing asset id=$id name=$NAME before upload..."); expect(workflow).toContain("-X DELETE \"$API/releases/$RELEASE_ID/assets/$id\""); diff --git a/tests/unit/releaseWorkflowMacBundle.test.ts b/tests/unit/releaseWorkflowMacBundle.test.ts index 832ad089..605534fb 100644 --- a/tests/unit/releaseWorkflowMacBundle.test.ts +++ b/tests/unit/releaseWorkflowMacBundle.test.ts @@ -2,20 +2,20 @@ import { describe, expect, it } from "vitest"; import { readFileSync } from "node:fs"; import path from "node:path"; -const releaseWorkflowPath = path.resolve( +const autoTagWorkflowPath = path.resolve( process.cwd(), - ".gitea/workflows/release.yml", + ".gitea/workflows/auto-tag.yml", ); -describe("release workflow macOS bundle path", () => { +describe("auto-tag release macOS bundle path", () => { it("does not reference the legacy TFTSR.app bundle name", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).not.toContain("/bundle/macos/TFTSR.app"); }); it("resolves the macOS .app bundle dynamically", () => { - const workflow = readFileSync(releaseWorkflowPath, "utf-8"); + const workflow = readFileSync(autoTagWorkflowPath, "utf-8"); expect(workflow).toContain("APP=$(find"); expect(workflow).toContain("-name \"*.app\"");