mirror of
https://github.com/ps5-linux/ps5-linux-image.git
synced 2026-07-15 21:42:27 +00:00
#20 added the distro directories but missed updating the dispatch choice enum and the 'all' matrix expansion, so the three new distros couldn't be triggered through CI.
271 lines
9.5 KiB
YAML
271 lines
9.5 KiB
YAML
name: Build Image
|
|
run-name: Build Image (${{ inputs.distro || 'all' }})
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
distro:
|
|
description: 'Distribution'
|
|
default: 'ubuntu2604'
|
|
type: choice
|
|
options: [all, ubuntu2604, arch, cachyos, fedora, proxmox, debian, bazzite, bazzite-deck, batocera]
|
|
workflow_call:
|
|
inputs:
|
|
distro:
|
|
type: string
|
|
default: 'ubuntu2604'
|
|
secrets:
|
|
R2_ACCESS_KEY_ID:
|
|
required: true
|
|
R2_SECRET_ACCESS_KEY:
|
|
required: true
|
|
R2_ENDPOINT:
|
|
required: true
|
|
R2_BUCKET:
|
|
required: true
|
|
|
|
jobs:
|
|
matrix:
|
|
runs-on: self-hosted
|
|
outputs:
|
|
distros: ${{ steps.set.outputs.distros }}
|
|
steps:
|
|
- id: set
|
|
run: |
|
|
INPUT="${{ inputs.distro || 'ubuntu2604' }}"
|
|
if [ "$INPUT" = "all" ]; then
|
|
echo 'distros=["ubuntu2604","arch","cachyos","fedora","proxmox","debian","bazzite","bazzite-deck","batocera"]' >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "distros=[\"$INPUT\"]" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
build:
|
|
needs: matrix
|
|
runs-on: self-hosted
|
|
timeout-minutes: 720
|
|
permissions:
|
|
contents: write
|
|
|
|
strategy:
|
|
fail-fast: true
|
|
max-parallel: 1
|
|
matrix:
|
|
distro: ${{ fromJson(needs.matrix.outputs.distros) }}
|
|
|
|
env:
|
|
CCACHE_DIR: /home/opc/ccache
|
|
|
|
steps:
|
|
- name: Clean image workspace
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -z "${GITHUB_WORKSPACE:-}" ] || [ "$GITHUB_WORKSPACE" = "/" ]; then
|
|
echo "Invalid GITHUB_WORKSPACE" >&2
|
|
exit 1
|
|
fi
|
|
sudo rm -rf "$GITHUB_WORKSPACE/image"
|
|
|
|
- name: Checkout image builder
|
|
uses: actions/checkout@v6
|
|
with:
|
|
path: image
|
|
|
|
- name: Build ${{ matrix.distro }} image
|
|
run: |
|
|
bash image/build_image.sh --distro "${{ matrix.distro }}"
|
|
|
|
- name: Set version info
|
|
id: version
|
|
run: |
|
|
psha=$(git -C image/work/ps5-linux-patches rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
kver=$(cat image/linux-bin/VERSION 2>/dev/null || echo "unknown")
|
|
ts=$(date -u +%Y%m%d-%H%M%S)
|
|
echo "psha=$psha" >> "$GITHUB_OUTPUT"
|
|
echo "kver=$kver" >> "$GITHUB_OUTPUT"
|
|
echo "ts=$ts" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Report
|
|
run: |
|
|
ls -lh image/output/*.img
|
|
sha256sum image/output/*.img
|
|
|
|
- name: Compress image
|
|
run: |
|
|
xz -T0 -4 -c image/output/ps5-${{ matrix.distro }}.img \
|
|
> image/output/ps5-${{ matrix.distro }}.img.xz
|
|
|
|
- name: Upload to R2
|
|
if: github.event_name != 'pull_request' && github.event_name != 'pull_request_target'
|
|
env:
|
|
RCLONE_CONFIG_R2_TYPE: s3
|
|
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
|
|
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
|
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
|
RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
|
RCLONE_CONFIG_R2_NO_CHECK_BUCKET: true
|
|
run: |
|
|
rclone copyto image/output/ps5-${{ matrix.distro }}.img.xz \
|
|
"r2:${{ secrets.R2_BUCKET }}/ps5-${{ matrix.distro }}.img.xz"
|
|
|
|
- name: Save build metadata
|
|
run: |
|
|
mkdir -p meta
|
|
sha256sum image/output/ps5-${{ matrix.distro }}.img.xz \
|
|
| sed 's|image/output/||' > meta/${{ matrix.distro }}.sha256
|
|
echo "${{ steps.version.outputs.kver }}" > meta/kver
|
|
echo "${{ steps.version.outputs.psha }}" > meta/psha
|
|
echo "${{ steps.version.outputs.ts }}" > meta/ts
|
|
|
|
- name: Upload build metadata
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: meta-${{ matrix.distro }}
|
|
path: meta/
|
|
retention-days: 1
|
|
|
|
release:
|
|
needs: build
|
|
runs-on: self-hosted
|
|
if: github.event_name != 'pull_request' && github.event_name != 'pull_request_target'
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Download build metadata
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
pattern: meta-*
|
|
path: meta
|
|
merge-multiple: true
|
|
|
|
- name: Prepare release body
|
|
id: body
|
|
uses: actions/github-script@v8
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const kver = fs.readFileSync('meta/kver', 'utf8').trim();
|
|
const psha = fs.readFileSync('meta/psha', 'utf8').trim();
|
|
const ts = fs.readFileSync('meta/ts', 'utf8').trim();
|
|
|
|
// Collect new checksums from this run
|
|
const newSums = {};
|
|
for (const f of fs.readdirSync('meta').filter(f => f.endsWith('.sha256'))) {
|
|
const distro = f.replace('.sha256', '');
|
|
newSums[distro] = fs.readFileSync(path.join('meta', f), 'utf8').trim();
|
|
}
|
|
|
|
// All known distros and their display names (order = table order)
|
|
const R2 = 'https://pub-561df4012f1a46fbbdf618d5cc5941f6.r2.dev';
|
|
const ALL_DISTROS = [
|
|
{ key: 'ubuntu2604', label: 'Ubuntu 26.04', file: 'ps5-ubuntu2604.img.xz' },
|
|
{ key: 'arch', label: 'Arch', file: 'ps5-arch.img.xz' },
|
|
{ key: 'cachyos', label: 'CachyOS', file: 'ps5-cachyos.img.xz' },
|
|
{ key: 'fedora', label: 'Fedora 44', file: 'ps5-fedora.img.xz' },
|
|
{ key: 'proxmox', label: 'Proxmox VE 8', file: 'ps5-proxmox.img.xz' },
|
|
{ key: 'debian', label: 'Debian 12', file: 'ps5-debian.img.xz' },
|
|
];
|
|
|
|
// Fetch existing release body to preserve distros not built this run
|
|
const existingSums = {};
|
|
try {
|
|
const { data: rel } = await github.rest.repos.getReleaseByTag({
|
|
...context.repo, tag: 'latest',
|
|
});
|
|
// Extract existing checksum lines (format: "hash filename")
|
|
const sumBlock = (rel.body || '').match(/```\n([\s\S]*?)```/);
|
|
if (sumBlock) {
|
|
for (const line of sumBlock[1].trim().split('\n')) {
|
|
const m = line.match(/^(\w+)\s+ps5-(\S+)\.img\.xz$/);
|
|
if (m) existingSums[m[2]] = line.trim();
|
|
}
|
|
}
|
|
// Also preserve distros that appear in the table even without checksums
|
|
for (const d of ALL_DISTROS) {
|
|
if (rel.body && rel.body.includes(d.file) && !existingSums[d.key]) {
|
|
existingSums[d.key] = '';
|
|
}
|
|
}
|
|
} catch (e) {
|
|
core.info('No existing release found, starting fresh');
|
|
}
|
|
|
|
// Merge: new checksums override existing ones
|
|
const mergedSums = { ...existingSums };
|
|
for (const [k, v] of Object.entries(newSums)) {
|
|
mergedSums[k] = v;
|
|
}
|
|
|
|
// Build the table — only include distros that have been built at least once
|
|
const rows = ALL_DISTROS
|
|
.filter(d => d.key in mergedSums || d.key in newSums)
|
|
.map(d => `| ${d.label} | [\`${d.file}\`](${R2}/${d.file}) |`);
|
|
|
|
// Combine all checksum lines
|
|
const allSumLines = ALL_DISTROS
|
|
.filter(d => mergedSums[d.key])
|
|
.map(d => mergedSums[d.key])
|
|
.join('\n');
|
|
|
|
const body = [
|
|
'PS5 Linux images — built from latest `main`.',
|
|
'',
|
|
`Kernel: \`${kver}\``,
|
|
`Patches: [\`${psha}\`](https://github.com/ps5-linux/ps5-linux-patches/commit/${psha})`,
|
|
`Built: \`${ts}\``,
|
|
'',
|
|
'| Image | Download |',
|
|
'|-------|----------|',
|
|
...rows,
|
|
'',
|
|
'**SHA256 checksums:**',
|
|
'```',
|
|
allSumLines,
|
|
'```',
|
|
].join('\n');
|
|
|
|
core.setOutput('text', body);
|
|
|
|
- name: Move latest tag to current commit
|
|
uses: actions/github-script@v8
|
|
with:
|
|
script: |
|
|
const ref = 'tags/latest';
|
|
try {
|
|
await github.rest.git.updateRef({
|
|
...context.repo, ref, sha: context.sha, force: true,
|
|
});
|
|
} catch (e) {
|
|
if (e.status !== 422) throw e;
|
|
await github.rest.git.createRef({
|
|
...context.repo, ref: 'refs/tags/latest', sha: context.sha,
|
|
});
|
|
}
|
|
|
|
- name: Create or update release
|
|
uses: softprops/action-gh-release@v3
|
|
with:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
tag_name: latest
|
|
name: PS5 Linux Image (latest)
|
|
body: ${{ steps.body.outputs.text }}
|
|
make_latest: true
|
|
|
|
- name: Refresh release publish date
|
|
uses: actions/github-script@v8
|
|
with:
|
|
script: |
|
|
const { data: rel } = await github.rest.repos.getReleaseByTag({
|
|
...context.repo, tag: 'latest',
|
|
});
|
|
// Toggling draft off->on->off re-publishes, resetting published_at
|
|
// to now while keeping the same release (reactions/comments survive).
|
|
await github.rest.repos.updateRelease({
|
|
...context.repo, release_id: rel.id, draft: true,
|
|
});
|
|
await github.rest.repos.updateRelease({
|
|
...context.repo, release_id: rel.id, draft: false, make_latest: 'true',
|
|
});
|
|
core.info(`re-published release ${rel.id}`);
|