diff --git a/.github/workflows/fork-windows-check.yml b/.github/workflows/fork-windows-check.yml index d89cf882d1..df03d8dde3 100644 --- a/.github/workflows/fork-windows-check.yml +++ b/.github/workflows/fork-windows-check.yml @@ -7,6 +7,7 @@ on: paths: - .github/workflows/fork-windows-check.yml - .github/workflows/build-windows.yml + - src/CMakeLists.txt - src/yuzu/** - src/yuzu_cmd/** - src/qt_common/** diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28de72131d..ce8c939540 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,9 +77,8 @@ jobs: with: pattern: frameropia-*-${{ inputs.sha }} path: artifacts + merge-multiple: false - # Asset names drop the commit sha: the tag already identifies the build, and stable names let - # the notes table link to them. (Not named dist/: the repository has one.) - name: Package release files shell: bash run: | @@ -87,34 +86,80 @@ jobs: rm -rf release-assets mkdir -p release-assets shopt -s nullglob - strip_sha() { sed "s/-${SHA}//" <<< "$1"; } - artifacts=(artifacts/*/) - ((${#artifacts[@]} > 0)) || { echo "No build artifacts were downloaded" >&2; exit 1; } - for artifact in "${artifacts[@]}"; do + artifact_dirs=(artifacts/*/) + + # download-artifact may extract the only matching artifact directly into + # artifacts/. Never mistake Qt plugin directories for build artifacts. + if [[ -s artifacts/frameropia.exe && -s artifacts/frameropia-cli.exe ]]; then + artifact_dirs=(artifacts/) + else + # Likewise a single Linux/macOS artifact can be flattened by the action. + root_packages=(artifacts/frameropia-"$SHA"-*.AppImage + artifacts/frameropia-"$SHA"-*.tar.gz + artifacts/frameropia-"$SHA"-*.zip + artifacts/frameropia-"$SHA"-*.dmg) + if (("${#root_packages[@]}" > 0)); then + artifact_dirs=(artifacts/) + fi + fi + (("${#artifact_dirs[@]}" > 0)) || { + echo "No build artifacts were downloaded" >&2 + exit 1 + } + + packaged=0 + for artifact in "${artifact_dirs[@]}"; do name=$(basename "$artifact") - appimages=("$artifact"*.AppImage) - mac_zips=("$artifact"*.zip) - if ((${#appimages[@]} > 0)); then - # Linux: ship the AppImage and tar.gz as they are. - for file in "${appimages[@]}" "$artifact"*.tar.gz; do - [[ -f "$file" ]] || continue - cp "$file" "release-assets/$(strip_sha "$(basename "$file")")" - done - elif ((${#mac_zips[@]} > 0)); then - # macOS: the app bundle zip and the dmg. - for file in "${mac_zips[@]}" "$artifact"*.dmg; do - [[ -f "$file" ]] || continue - cp "$file" "release-assets/$(strip_sha "$(basename "$file")")" - done - else - # Windows: upload-artifact stores the bin folder; zip it once for the release. - (cd "$artifact" && zip -qr "${GITHUB_WORKSPACE}/release-assets/$(strip_sha "$name").zip" .) + if [[ "$artifact" == artifacts/ ]]; then + if [[ -s artifacts/frameropia.exe ]]; then + name="frameropia-windows-x86_64-$SHA" + else + first="${root_packages[0]##*/}" + platform="${first#frameropia-$SHA-}" + platform="${platform%%.*}" + name="frameropia-$platform-$SHA" + fi fi + case "$name" in + frameropia-windows-*-"$SHA") + # A valid Windows archive contains BOTH complete executables, + # their DLLs and Qt plugin subdirectories in ONE ZIP. + test -s "$artifact/frameropia.exe" + test -s "$artifact/frameropia-cli.exe" + out="release-assets/${name%-$SHA}.zip" + (cd "$artifact" && zip -qr "$GITHUB_WORKSPACE/$out" .) + unzip -Z1 "$out" | grep -qx 'frameropia.exe' + unzip -Z1 "$out" | grep -qx 'frameropia-cli.exe' + packaged=$((packaged+1)) + ;; + frameropia-linux-*-"$SHA") + platform="${name#frameropia-}" + platform="${platform%-$SHA}" + for ext in AppImage tar.gz; do + file="$artifact/frameropia-$SHA-$platform.$ext" + [[ -s "$file" ]] || continue + cp "$file" "release-assets/frameropia-$platform.$ext" + packaged=$((packaged+1)) + done + ;; + frameropia-macos-*-"$SHA") + platform="${name#frameropia-}" + platform="${platform%-$SHA}" + for ext in zip dmg; do + file="$artifact/frameropia-$SHA-$platform.$ext" + [[ -s "$file" ]] || continue + cp "$file" "release-assets/frameropia-$platform.$ext" + packaged=$((packaged+1)) + done + ;; + *) + echo "Unexpected build artifact directory: $name" >&2 + exit 1 + ;; + esac done - files=(release-assets/*) - ((${#files[@]} > 0)) || { echo "Build artifacts contained no release files" >&2; exit 1; } - printf 'Prepared %s release assets\n' "${#files[@]}" - ls -la release-assets + ((packaged > 0)) || { echo "No valid release assets" >&2; exit 1; } + ls -lah release-assets - name: Write release notes shell: bash diff --git a/.github/workflows/repair-v0.0.1.yml b/.github/workflows/repair-v0.0.1.yml new file mode 100644 index 0000000000..fb78dc694d --- /dev/null +++ b/.github/workflows/repair-v0.0.1.yml @@ -0,0 +1,98 @@ +name: repair-v0.0.1-release + +# One-time repair of a published release that accidentally uploaded Qt plugin folders. +# Reuses the exact successful v0.0.1 Windows artifact, without changing the git tag. +on: + push: + branches: [nx2] + paths: + - .github/workflows/repair-v0.0.1.yml + +permissions: + contents: write + actions: read + +jobs: + repair: + if: github.repository == 'Framerr/Frameropia' + runs-on: ubuntu-24.04 + env: + GH_TOKEN: ${{ github.token }} + TAG: v0.0.1 + ORIGINAL_SHA: 4db9b59173315eace20b03d6178e77a2d4f36445 + ARCHIVE: frameropia-windows-x86_64.zip + steps: + - name: Check out trusted source + uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Download the successful original Windows build + uses: actions/download-artifact@v8 + with: + name: eglantine-windows-x86_64-4db9b59173315eace20b03d6178e77a2d4f36445 + run-id: 42410526945 + github-token: ${{ github.token }} + path: original-build + + - name: Verify release tag and prepare a complete ZIP + shell: bash + run: | + set -euo pipefail + actual=$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$TAG" --jq '.object.sha') + [[ "$actual" == "$ORIGINAL_SHA" ]] || { + echo "Release tag does not point to the original build; refusing to modify it" >&2 + exit 1 + } + test -s original-build/eglantine.exe + test -s original-build/eden-cli.exe + (cd original-build && zip -qr "../$ARCHIVE" .) + test -s "$ARCHIVE" + unzip -Z1 "$ARCHIVE" | grep -qx 'eglantine.exe' + unzip -Z1 "$ARCHIVE" | grep -qx 'eden-cli.exe' + unzip -Z1 "$ARCHIVE" | grep -qE '^(plugins/|platforms/)' + echo "Verified the original binaries and Qt runtime files in $ARCHIVE" + + - name: Repair release notes and published assets + shell: bash + run: | + set -euo pipefail + gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null + gh release upload "$TAG" "$ARCHIVE" --repo "$GITHUB_REPOSITORY" --clobber + + cat docs/releases/v0.0.1.md > repaired-notes.md + cat >>repaired-notes.md <<'NOTES' + + ## Windows download + + [Download the complete Windows x86_64 archive](https://github.com/Framerr/Frameropia/releases/download/v0.0.1/frameropia-windows-x86_64.zip) + + **Historical executable names:** this v0.0.1 build was compiled before the Frameropia application rebrand. Extract the entire ZIP and run `eglantine.exe`; the included CLI is `eden-cli.exe`. Future builds use `frameropia.exe` and `frameropia-cli.exe`. Do not extract Qt plugin folders separately. + NOTES + + gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" \ + --title 'Frameropia v0.0.1 (legacy test build)' \ + --notes-file repaired-notes.md --prerelease + + # Only remove the eight known accidental Qt plugin archives. + for stale in generic.zip iconengines.zip imageformats.zip \ + networkinformation.zip platforms.zip plugins.zip styles.zip tls.zip; do + if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets \ + --jq '.assets[].name' | grep -Fxq "$stale"; then + gh release delete-asset "$TAG" "$stale" \ + --repo "$GITHUB_REPOSITORY" --yes + fi + done + + - name: Verify the corrected release + shell: bash + run: | + set -euo pipefail + assets=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets \ + --jq '.assets[].name') + test "$assets" = "$ARCHIVE" || { + echo "Unexpected assets remaining:" >&2 + echo "$assets" >&2 + exit 1 + } + gh release view "$TAG" --repo "$GITHUB_REPOSITORY" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c15294ff7f..7f54849854 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -285,7 +285,7 @@ endif() if(YUZU_CMD) add_subdirectory(yuzu_cmd) - set_target_properties(yuzu-cmd PROPERTIES OUTPUT_NAME "eden-cli") + set_target_properties(yuzu-cmd PROPERTIES OUTPUT_NAME "frameropia-cli") endif() if(ENABLE_QT) diff --git a/tools/ci/check-frameropia-branding.sh b/tools/ci/check-frameropia-branding.sh index 9e3c37db8e..d872178668 100644 --- a/tools/ci/check-frameropia-branding.sh +++ b/tools/ci/check-frameropia-branding.sh @@ -17,6 +17,7 @@ require src/yuzu/configuration/configure.ui "Frameropia Configuration" require CMakeModules/GenerateSCMRev.cmake 'set(REPO_NAME "Frameropia")' require src/yuzu/CMakeLists.txt 'OUTPUT_NAME "frameropia"' require src/yuzu_cmd/CMakeLists.txt 'OUTPUT_NAME "frameropia-cli"' +require src/CMakeLists.txt 'OUTPUT_NAME "frameropia-cli"' require .github/workflows/build-windows.yml 'frameropia.exe' require .github/workflows/build-linux.yml 'build/release/bin/frameropia' require .github/workflows/build-macos.yml 'build/release/bin/frameropia.app'