From 96a6ba196c72e955c3db822d93da38fce8cd7045 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Thu, 23 Apr 2026 16:09:59 -0500 Subject: Fix VFS rmdir, prefix/launch issues, add version + beta channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - VFS: add mo2_rmdir + OverwriteManager::removeDirectory so Wrye Bash shutil.rmtree stops failing with WinError 267 (issue #47). - FileRenamer: case-insensitive fallback via new resolvePathCaseInsensitive walks each path component; bulk hide in Conflict tab no longer dies with a misleading "Input/output error" when DirectoryEntry normalised parent dir case (issue #54). formatSystemMessage stops aliasing Windows error code 5 to errno 5 (EIO). - Versioning: FLUORINE_VERSION_* + fluorine_build_info.h generated from CMake; Linux createVersionInfo returns Fluorine's version. About dialog shows Fluorine version + MO2 engine + commit. Beta builds stamp "B" (issue #51). - CI: ci.yml determines channel from ref (v* tags = stable, main = beta), publishes a rolling `beta` GitHub release whose body carries a machine-parseable fluorine-meta block (timestamp, commit) for the in-app updater. - Updater: new FluorineUpdater polls GitHub API on startup, compares against embedded metadata, notifies on new release without auto-install. Channel toggle piggybacks on the existing "beta versions" checkbox. - Bethesda plugins: determineMyGamesPath no longer creates Documents/My Games/ for every possible title at plugin load; only games with a detected install path get their dirs created (issue #55). - Starfield: dataDirectory() on Linux now points at /Data instead of My Games/Starfield/Data so the single FUSE mount lands where SFSE loads plugins; My Games Data becomes a secondary symlinked mapping (issue #56). - Prefix resolution: prefer Fluorine config, then explicit fluorine/prefix_path, then legacy Settings/* keys (with a warning) so auto-detected Heroic/Bottles prefixes can't silently override a user- configured Fluorine prefix (issue #52). compatDataPathFromPrefix no longer hands Proton the wrong parent dir for plain wine prefixes. - xrandr: ensureXrandrInstalled back-fills the helper for existing SLR installs, prefix init runs it before wineboot, SLR wrap exposes xrandr-bin via --filesystem= and prepends PATH inside the container (issue #49). - Process tracking: drop the wineserver-as-last-resort fallback that made MO2 hang on Proton's session manager after game exit. Rescan the prefix for matching game executables instead (covers reparented launcher children like f4se_loader → Fallout4.exe). Unlock button now kills wineserver for the prefix (SIGTERM then SIGKILL on timeout). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to '.github') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9c03f5..0a5f551 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,18 @@ jobs: restore-keys: | ccache-${{ runner.os }}- + - name: Determine build channel + id: channel + run: | + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + echo "channel=stable" >> "$GITHUB_OUTPUT" + echo "timestamp=" >> "$GITHUB_OUTPUT" + else + echo "channel=beta" >> "$GITHUB_OUTPUT" + echo "timestamp=$(date -u +%Y%m%d%H%M)" >> "$GITHUB_OUTPUT" + fi + echo "commit=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + - name: Build inside container run: | mkdir -p ~/.cache/fluorine-ccache @@ -58,10 +70,25 @@ jobs: -e CCACHE_SLOPPINESS=time_macros,include_file_mtime,include_file_ctime,pch_defines \ -e CCACHE_MAXSIZE=5G \ -e BUILD_MODE=tarball \ + -e FLUORINE_BUILD_CHANNEL=${{ steps.channel.outputs.channel }} \ + -e FLUORINE_BUILD_TIMESTAMP=${{ steps.channel.outputs.timestamp }} \ + -e FLUORINE_BUILD_COMMIT=${{ steps.channel.outputs.commit }} \ -w /src \ fluorine-builder:latest \ bash -c 'ccache -s; bash /src/docker/build-inner.sh; echo "=== ccache stats after build ==="; ccache -s' + - name: Package tarball + run: | + cd build + if [[ "${{ steps.channel.outputs.channel }}" == "beta" ]]; then + ARCHIVE_NAME="fluorine-manager-beta.tar.gz" + else + ARCHIVE_NAME="fluorine-manager-${GITHUB_REF_NAME}.tar.gz" + fi + tar czf "${ARCHIVE_NAME}" fluorine-manager/ + echo "archive=${ARCHIVE_NAME}" >> "$GITHUB_ENV" + echo "archive_path=build/${ARCHIVE_NAME}" >> "$GITHUB_ENV" + - name: Upload build uses: actions/upload-artifact@v4 with: @@ -70,6 +97,81 @@ jobs: compression-level: 6 if-no-files-found: warn + # ------------------------------------------------------------------- + # Beta rolling release: every push to main overwrites the `beta` tag's + # release assets so the in-app updater always sees the latest build + # without cluttering the release history with new tags. + # ------------------------------------------------------------------- + - name: Publish beta rolling release + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + run: | + TAG="beta" + BETA_TS="${{ steps.channel.outputs.timestamp }}" + BETA_COMMIT="${GITHUB_SHA}" + BETA_SHORT="${BETA_COMMIT:0:7}" + TITLE="Fluorine Manager beta ${BETA_TS} (${BETA_SHORT})" + NOTES_FILE="$(mktemp)" + { + echo "Rolling beta build from main @ ${BETA_SHORT}." + echo "" + echo "- Channel: beta" + echo "- Timestamp (UTC): ${BETA_TS}" + echo "- Commit: ${BETA_COMMIT}" + echo "" + echo "This release is overwritten with each successful CI build on main." + echo "For stable releases, see tagged v* releases." + echo "" + # Machine-parseable block used by the in-app updater to decide + # whether the currently-installed beta build already matches. Do + # not remove or reformat — the updater reads it line-by-line. + echo "" + } > "${NOTES_FILE}" + + # Move the rolling tag to the current commit. + git tag -f "${TAG}" "${GITHUB_SHA}" + git push -f origin "refs/tags/${TAG}" + + if gh release view "${TAG}" >/dev/null 2>&1; then + gh release edit "${TAG}" \ + --title "${TITLE}" \ + --notes-file "${NOTES_FILE}" \ + --prerelease + # Replace the tarball asset (clobber wins over upload+delete race). + gh release upload "${TAG}" "${archive_path}" --clobber + else + gh release create "${TAG}" "${archive_path}" \ + --title "${TITLE}" \ + --notes-file "${NOTES_FILE}" \ + --prerelease + fi + + # ------------------------------------------------------------------- + # Stable release: triggered by pushing a v* tag. Uploads the tagged + # archive as a normal (non-prerelease) GitHub release. + # ------------------------------------------------------------------- + - name: Publish stable release + if: startsWith(github.ref, 'refs/tags/v') + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + run: | + TAG="${GITHUB_REF_NAME}" + if gh release view "${TAG}" >/dev/null 2>&1; then + gh release upload "${TAG}" "${archive_path}" --clobber + else + gh release create "${TAG}" "${archive_path}" \ + --title "Fluorine Manager ${TAG}" \ + --generate-notes + fi + build-nixos-mobase: runs-on: ubuntu-latest steps: -- cgit v1.3.1