diff --git a/.github/workflows/linux_build_flatpak.yml b/.github/workflows/linux_build_flatpak.yml new file mode 100644 index 0000000000..5c0f73611d --- /dev/null +++ b/.github/workflows/linux_build_flatpak.yml @@ -0,0 +1,177 @@ +name: Flatpak Build Steps + +on: + workflow_call: + inputs: + jobName: + required: true + type: string + artifactPrefixName: + required: true + type: string + os: + required: false + type: string + default: ubuntu-22.04 + platform: + required: false + type: string + default: x64 + compiler: + required: true + type: string + cmakeflags: + required: true + type: string + publish: + required: false + type: boolean + default: false + patchesUrl: + required: false + type: string + default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download + fetchTags: + required: false + type: boolean + default: false + stableBuild: + required: false + type: boolean + default: false + +jobs: + build_linux: + name: ${{ inputs.jobName }} + runs-on: ${{ inputs.os }} + container: + image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.9 + options: --privileged + timeout-minutes: 60 + + steps: + - name: Checkout Repository + uses: actions/checkout@v6 + with: + set-safe-directory: ${{ env.GITHUB_WORKSPACE }} + # 10 here, since the odds of having 10 untagged commits in a row should be slim to none + # This is required for the tagging logic in generate-metainfo.sh + fetch-depth: 10 + fetch-tags: true + + # Work around container ownership issue + - name: Set Safe Directory + shell: bash + run: git config --global --add safe.directory "*" + + - name: Add stable release identifier file + if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }} + shell: bash + run: | + echo "#define DEFAULT_UPDATER_CHANNEL \"stable\"" > ./pcsx2-qt/DefaultUpdaterChannel.h + cat ./pcsx2-qt/DefaultUpdaterChannel.h + + - name: Prepare Artifact Metadata + id: artifact-metadata + shell: bash + env: + PREFIX: ${{ inputs.artifactPrefixName }} + EVENT_NAME: ${{ github.event_name }} + PR_TITLE: ${{ github.event.pull_request.title }} + PR_NUM: ${{ github.event.pull_request.number }} + PR_SHA: ${{ github.event.pull_request.head.sha }} + run: ./.github/workflows/scripts/common/name-artifacts.sh + + - name: Download patches + run: | + cd bin/resources + wget "${{ inputs.patchesUrl }}/patches.zip" + + - name: Validate manifest + run: | + flatpak-builder-lint manifest .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json + + - name: Build Flatpak (beta) + if: ${{ inputs.stableBuild == false || inputs.stableBuild == 'false' }} + uses: flatpak/flatpak-github-actions/flatpak-builder@401fe28a8384095fc1531b9d320b292f0ee45adb + with: + bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak + upload-artifact: false + manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json + arch: x86_64 + build-bundle: true + verbose: true + mirror-screenshots-url: https://dl.flathub.org/media + branch: beta + cache: true + restore-cache: true + cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json', '.github/workflows/scripts/common/*.patch') }} + + - name: Build Flatpak (stable) + if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }} + uses: flatpak/flatpak-github-actions/flatpak-builder@401fe28a8384095fc1531b9d320b292f0ee45adb + with: + bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak + upload-artifact: false + manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json + arch: x86_64 + build-bundle: true + verbose: true + mirror-screenshots-url: https://dl.flathub.org/media + branch: stable + cache: true + restore-cache: true + cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }} + + #- name: Validate build + # run: | + # flatpak-builder-lint repo repo + + - name: Push to Flathub (beta) + if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }} + uses: flatpak/flatpak-github-actions/flat-manager@401fe28a8384095fc1531b9d320b292f0ee45adb + with: + flat-manager-url: https://hub.flathub.org/ + repository: beta + token: ${{ secrets.FLATHUB_BETA_TOKEN }} + build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + - name: Push to Flathub (stable) + if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }} + uses: flatpak/flatpak-github-actions/flat-manager@401fe28a8384095fc1531b9d320b292f0ee45adb + with: + flat-manager-url: https://hub.flathub.org/ + repository: stable + token: ${{ secrets.FLATHUB_TOKEN }} + build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + # NOTE - this is done after on purpose so the flatpak file is wherever it needs to be for the previous pushes + - name: Prepare artifacts folder + # NOTE - 'flatpak-builder' dumps the artifact out into the current directory + run: | + mkdir -p "$GITHUB_WORKSPACE"/ci-artifacts/ + mv "./${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak" "$GITHUB_WORKSPACE"/ci-artifacts/ + + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: ${{ steps.artifact-metadata.outputs.artifact-name }} + path: ci-artifacts + report-error: + runs-on: ubuntu-latest + needs: build_linux + if: always() && needs.build_linux.result == 'failure' && inputs.publish == true + + steps: + - uses: actions/checkout@v6 + + - name: Push Discord Webhook + env: + OWNER: PCSX2 + REPO: pcsx2 + DISCORD_BUILD_WEBHOOK: ${{ secrets.DISCORD_BUILD_WEBHOOK }} + GITHUB_TOKEN: ${{ github.token }} + run: | + cd ./.github/workflows/scripts/releases/announce-release + npm ci + FLATHUB_FAILURE=1 node index.js diff --git a/.github/workflows/scripts/releases/announce-release/index.js b/.github/workflows/scripts/releases/announce-release/index.js new file mode 100644 index 0000000000..a1e57e72d9 --- /dev/null +++ b/.github/workflows/scripts/releases/announce-release/index.js @@ -0,0 +1,97 @@ +import { MessageEmbed, WebhookClient } from "discord.js"; +import { Octokit } from "@octokit/rest"; +import { throttling } from "@octokit/plugin-throttling"; +import { retry } from "@octokit/plugin-retry"; + +let owner = process.env.OWNER; +let repo = process.env.REPO; + +Octokit.plugin(throttling); +Octokit.plugin(retry); +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, + userAgent: `${owner}/${repo}`, + log: { + debug: () => { }, + info: () => { }, + warn: console.warn, + error: console.error + }, + throttle: { + onRateLimit: (retryAfter, options) => { + octokit.log.warn( + `Request quota exhausted for request ${options.method} ${options.url}` + ); + + // Retry twice after hitting a rate limit error, then give up + if (options.request.retryCount <= 2) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + octokit.log.warn( + `Abuse detected for request ${options.method} ${options.url}` + ); + }, + } +}); + +let embed; + +if (process.env.FLATHUB_FAILURE === undefined) +{ + if (process.env.TAG_VAL === undefined || process.env.TAG_VAL === "") { + console.log(`Not announcing - TAG_VAL not defined`); + process.exit(1); + } + + const { data: releaseInfo } = await octokit.rest.repos.getReleaseByTag({ + owner: owner, + repo: repo, + tag: process.env.TAG_VAL, + }); + + if (releaseInfo === undefined) { + console.log(`Not announcing - could not locate release with tag ${process.env.TAG_VAL}`); + process.exit(1); + } + + if (!releaseInfo.prerelease) { + console.log("Not announcing - release was not a pre-release (aka a Nightly)"); + process.exit(0); + } + + // Publish Webhook + embed = new MessageEmbed() + .setColor('#FF8000') + .setTitle('New PCSX2 Nightly Build Available!') + .setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).") + .addFields( + { name: 'Version', value: releaseInfo.tag_name, inline: true }, + { name: 'Installation Steps', value: '[See Here](https://pcsx2.net/docs/category/setup)', inline: true }, + { name: 'Included Changes', value: releaseInfo.body, inline: false } + ); + console.log(embed); +} +else +{ + // Flathub upload failure + + embed = new MessageEmbed() + .setColor('#FF0000') + .setTitle('PCSX2 Failed to Build/Upload to FlatHub') + .setDescription("Please check the latest Flathub build job to determine the root cause.") + console.log(embed); +} + +// Get all webhooks, simple comma-sep string +const webhookUrls = process.env.DISCORD_BUILD_WEBHOOK.split(","); + +for (const url of webhookUrls) { + const webhookClient = new WebhookClient({ url: url }); + await webhookClient.send({ + embeds: [embed], + }); +}