From dd9d8b89e8bb28eac34654536525916deddd9a9d Mon Sep 17 00:00:00 2001 From: tranch Date: Sun, 20 Sep 2026 10:56:18 +0800 Subject: Pin testing base to Bazzite 44.20260919 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b6b8df..1639aab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ env: IMAGE_LOGO_URL: ${{ vars.IMAGE_LOGO_URL || 'https://avatars.githubusercontent.com/u/120078124?s=200&v=4' }} DEFAULT_TAG: ${{ vars.DEFAULT_TAG || 'stable' }} BIB_IMAGE: ${{ vars.BIB_IMAGE || 'quay.io/centos-bootc/bootc-image-builder:latest' }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260908' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} @@ -95,7 +95,7 @@ jobs: - name: Generate Version and Tags id: gen-version env: - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260908' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} run: | set -euo pipefail @@ -162,7 +162,7 @@ jobs: id: build-image env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260908' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} -- cgit v1.2.3 From a2c9b4aa17b0c28d0f0d34de13fe14f35c3da39e Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 23 Sep 2026 16:50:28 +0800 Subject: feat: organize upstream release notes --- .github/scripts/generate_changelog.py | 170 ++++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 16 deletions(-) (limited to '.github') diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 57f7ba9..0bcf369 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -7,6 +7,8 @@ import argparse import json import os import re +import urllib.error +import urllib.request import subprocess import tempfile from pathlib import Path @@ -73,6 +75,92 @@ def markdown_version(value: str | None) -> str: return value or "—" +MAJOR_PACKAGES = { + "kernel": "Kernel", + "kernel-core": "Kernel", + "kernel-modules": "Kernel", + "kernel-modules-core": "Kernel", + "kernel-modules-extra": "Kernel", + "kernel-tools": "Kernel", + "kernel-devel": "Kernel", + "kernel-headers": "Kernel", + "kernel-lts": "Kernel (Nvidia LTS)", + "linux-firmware": "Firmware", + "mesa-dri-drivers": "Mesa", + "mesa-filesystem": "Mesa", + "mesa-libEGL": "Mesa", + "mesa-libGL": "Mesa", + "mesa-libgbm": "Mesa", + "mesa-va-drivers": "Mesa", + "mesa-vulkan-drivers": "Mesa", + "gamescope": "Gamescope", + "gamescope-session": "Gamescope Session", + "mangohud": "MangoHUD", + "inputplumber": "InputPlumber", + "opengamepadui": "OpenGamepadUI", + "powerstation": "PowerStation", + "steamos-manager": "SteamOS-Manager", + "umu-launcher": "UMU Launcher", + "bazaar": "Bazaar", + "distrobox": "Distrobox", + "gnome-shell": "Gnome", + "plasma-desktop": "KDE", + "waydroid": "Waydroid", +} + + +def major_package_rows( + current_packages: dict[str, str], + previous_packages: dict[str, str] | None, +) -> list[str]: + selected: dict[str, tuple[str | None, str | None]] = {} + for name, current in current_packages.items(): + display_name = MAJOR_PACKAGES.get(name) + if not display_name: + continue + previous = (previous_packages or {}).get(name) + selected[display_name] = (previous, current) + + rows = [] + for display_name, (old, new) in selected.items(): + version = markdown_version(new) + if old and new and old != new: + version = f"{old} ➡️ {new}" + rows.append(f"| **{display_name}** | {version} |") + return rows + + +def all_image_rows(changes: list[tuple[str, str | None, str | None]]) -> list[str]: + rows = [] + for name, old, new in changes: + icon = "➕" if old is None else "➖" if new is None else "🔄" + rows.append( + f"| {icon} | `{name}` | {markdown_version(old)} | {markdown_version(new)} |" + ) + return rows + + +def upstream_release_commit(tag: str) -> str | None: + try: + request = urllib.request.Request( + f"https://api.github.com/repos/ublue-os/bazzite/git/ref/tags/{tag}", + headers={"Accept": "application/vnd.github+json", "User-Agent": "AeroCore-OS-release-notes"}, + ) + with urllib.request.urlopen(request, timeout=30) as response: + data = json.load(response) + obj = data["object"] + if obj.get("type") == "tag": + request = urllib.request.Request( + f"https://api.github.com/repos/ublue-os/bazzite/git/tags/{obj['sha']}", + headers={"Accept": "application/vnd.github+json", "User-Agent": "AeroCore-OS-release-notes"}, + ) + with urllib.request.urlopen(request, timeout=30) as response: + obj = json.load(response)["object"] + return obj.get("sha") + except (urllib.error.URLError, urllib.error.HTTPError, KeyError, json.JSONDecodeError): + return None + + def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--image", required=True, help="registry/repository without tag") @@ -89,6 +177,7 @@ def main() -> None: current_info = image_info(args.image, args.current) current_packages = package_map(fetch_sbom(args.image, current_info["Digest"])) + base_image = current_info.get("Labels", {}).get("org.opencontainers.image.base.name") previous_packages: dict[str, str] | None = None if previous: try: @@ -107,34 +196,83 @@ def main() -> None: changes.append((name, old, new)) previous_info = image_info(args.image, previous) if previous else {} + previous_base = previous_info.get("Labels", {}).get("org.opencontainers.image.base.name", "") + previous_base_tag = previous_base.rpartition(":")[2] + current_base_tag = base_image.rpartition(":")[2] if base_image else "" + start_revision = upstream_release_commit(previous_base_tag) if previous_base_tag else None + end_revision = upstream_release_commit(current_base_tag) if current_base_tag else None + upstream_commits = [] + if start_revision and end_revision and start_revision != end_revision: + request = urllib.request.Request( + f"https://api.github.com/repos/ublue-os/bazzite/compare/{start_revision}...{end_revision}", + headers={"Accept": "application/vnd.github+json", "User-Agent": "AeroCore-OS-release-notes"}, + ) + with urllib.request.urlopen(request, timeout=60) as response: + compare = json.load(response) + upstream_commits = [ + ( + item["sha"], + item["commit"]["message"].splitlines()[0], + item["commit"]["author"].get("name", "Unknown"), + ) + for item in compare.get("commits", []) + ] + start_revision = previous_info.get("Labels", {}).get("org.opencontainers.image.revision") end_revision = current_info.get("Labels", {}).get("org.opencontainers.image.revision") - commits = ( - run("git", "log", "--format=%H%x09%s%x09%an", f"{start_revision}..{end_revision}").splitlines() - if start_revision and end_revision + aerocore_commits = ( + [ + (item.split("\t", 2)[0], item.split("\t", 2)[1], item.split("\t", 2)[2]) + for item in run( + "git", "log", "--format=%H%x09%s%x09%an", f"{start_revision}..{end_revision}" + ).splitlines() + ] + if start_revision and end_revision and start_revision != end_revision else [] ) lines = [args.handwritten.strip() or f"This is an automatically generated changelog for release `{args.current}`.", ""] + if base_image: + base_name, _, base_tag = base_image.rpartition(":") + if base_name and base_tag: + base_repo = base_name.removeprefix("docker://") + upstream_version = re.sub(r"^(?:stable|testing|testing-candidate)-", "", base_tag) + lines.append( + f"Based on upstream [{upstream_version}](https://github.com/ublue-os/bazzite/releases/tag/{base_tag}) " + f"(`{base_repo}`)." + ) + else: + lines.append(f"Based on upstream image `{base_image}`.") + lines.append("") if previous: - lines.append(f"From previous `{args.channel}` version `{previous}` there have been the following package changes.") - else: - lines.append("No previous release was found for this channel; package changes are shown against an empty baseline.") - lines += ["", "### Package changes", "", "| Name | Previous | New |", "| --- | --- | --- |"] - if previous and previous_packages is None: - lines.append("| — | Previous release has no attached SBOM | Diff starts with the next release |") - elif not changes: - lines.append("| — | — | — |") + lines.append(f"From previous `{args.channel}` version `{previous}` there have been the following changes. One package per new version shown.") else: - lines += [f"| `{name}` | {markdown_version(old)} | {markdown_version(new)} |" for name, old, new in changes] + lines.append("No previous release was found for this channel; changes are shown against an empty baseline.") + + lines += ["", "### Major packages", "", "| Name | Version |", "| --- | --- |"] + major_rows = major_package_rows(current_packages, previous_packages) + lines.extend(major_rows or ["| — | No major package changes |"]) lines += ["", "### Commits", "", "| Hash | Subject | Author |", "| --- | --- | --- |"] - for commit in commits: - commit_hash, subject, author = commit.split("\t", 2) - lines.append(f"| [{commit_hash[:7]}](https://github.com/{args.repository}/commit/{commit_hash}) | {subject} | {author} |") - if not commits: + if upstream_commits: + lines.append("| | **Upstream Bazzite** | | |") + for commit_hash, subject, author in upstream_commits: + lines.append(f"| | **[{commit_hash[:7]}](https://github.com/ublue-os/bazzite/commit/{commit_hash})** | {subject} | {author} |") + if aerocore_commits: + lines.append("| | **AeroCore OS** | | |") + for commit_hash, subject, author in aerocore_commits: + lines.append(f"| | **[{commit_hash[:7]}](https://github.com/{args.repository}/commit/{commit_hash})** | {subject} | {author} |") + if not upstream_commits and not aerocore_commits: lines.append("| — | No commit range available | — |") + lines += ["", "### All Images", "", "| | Name | Previous | New |", "| --- | --- | --- | --- |"] + if previous and previous_packages is None: + lines.append("| — | Previous release has no attached SBOM | — | Diff starts with the next release |") + elif not changes: + lines.append("| — | No package changes | — | — |") + else: + lines.extend(all_image_rows(changes)) + lines += ["", "### How to switch", "", "For current users, switch to the channel image with:", "", "```bash", f"sudo bootc switch {args.image}:{args.channel}", "", "# Or switch to this exact image:", f"sudo bootc switch {args.image}:{args.current}", "```", ""] args.output.write_text("\n".join(lines)) -- cgit v1.2.3 From fa7a54f7d51f3086f35239d7117b9c5988a96c68 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 23 Sep 2026 16:50:28 +0800 Subject: build: update Bazzite base to 44.20260921 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1639aab..0bb6f79 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ env: IMAGE_LOGO_URL: ${{ vars.IMAGE_LOGO_URL || 'https://avatars.githubusercontent.com/u/120078124?s=200&v=4' }} DEFAULT_TAG: ${{ vars.DEFAULT_TAG || 'stable' }} BIB_IMAGE: ${{ vars.BIB_IMAGE || 'quay.io/centos-bootc/bootc-image-builder:latest' }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} @@ -95,7 +95,7 @@ jobs: - name: Generate Version and Tags id: gen-version env: - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} run: | set -euo pipefail @@ -162,7 +162,7 @@ jobs: id: build-image env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260919' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} -- cgit v1.2.3 From 01f191a5e2e3ca5ac6884b09f6ffcbfd5094f555 Mon Sep 17 00:00:00 2001 From: tranch Date: Mon, 28 Sep 2026 11:14:04 +0800 Subject: Align Live and installer ISO commands Use build-live-iso for the Titanoboa Live ISO workflow and build-installer-iso for bootc-image-builder installer ISO images. Rename the associated workflow and build script, and update local run instructions accordingly. --- .github/workflows/build-installer-iso.yml | 167 ------------------------------ .github/workflows/build-live-iso.yml | 167 ++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 167 deletions(-) delete mode 100644 .github/workflows/build-installer-iso.yml create mode 100644 .github/workflows/build-live-iso.yml (limited to '.github') diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml deleted file mode 100644 index da3ef10..0000000 --- a/.github/workflows/build-installer-iso.yml +++ /dev/null @@ -1,167 +0,0 @@ -name: Build Live ISOs - -on: - workflow_dispatch: - inputs: - image_tag: - description: "AeroCore image tag to install" - required: false - default: latest - type: string - workflow_call: - -permissions: {} - -concurrency: - group: ${{ github.workflow }}-${{ github.ref || github.run_id }} - cancel-in-progress: true - -jobs: - build-installer-iso: - name: Build KDE live ISO - runs-on: ubuntu-24.04 - permissions: - contents: read - packages: read - - env: - IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} - IMAGE_NAME: ${{ vars.IMAGE_NAME || github.event.repository.name }} - IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} - ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} - # Keep these aligned with the Fedora major used by the target bazzite-deck base image. - LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:44 - FEDORA_VERSION: "44" - OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} - - steps: - - name: Maximize build space - uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 - with: - remove-codeql: true - - - name: Mount container storage BTRFS loopback - run: | - sudo truncate -s 70G /mnt/podman-storage.img - sudo mkfs.btrfs -f /mnt/podman-storage.img - sudo podman system reset --force - sudo systemctl stop podman.service - sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage - sudo systemctl start podman.service - - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - - name: Prepare image references - run: | - image_name="${IMAGE_NAME,,}" - image_registry="${IMAGE_REGISTRY,,}" - echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" - echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" - - - name: Login to GHCR - run: | - echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ - --username '${{ github.actor }}' --password-stdin - - - name: Pull AeroCore install image - run: | - sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" - - - name: Build installer ISO payload - run: | - mkdir -p output - ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://${IMAGE_REGISTRY}/${IMAGE_NAME}}" - install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" - install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" - install_image_ref="${install_image_ref#docker://}" - sudo podman tag \ - "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ - "${install_image_ref}:${IMAGE_TAG}" - sudo podman save \ - --format oci-archive \ - --output output/install-payload.oci \ - "${install_image_ref}:${IMAGE_TAG}" - - sudo podman build \ - --cap-add sys_admin \ - --security-opt label=disable \ - --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ - --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ - --build-arg "INSTALL_IMAGE_TAG=${IMAGE_TAG}" \ - --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ - --tag localhost/aerocore-os-installer:latest \ - --file installer/Containerfile \ - . - - - name: Build ISO - id: build - uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr - with: - image-ref: localhost/aerocore-os-installer:latest - iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso - - - name: Normalize ISO output path - shell: bash - env: - GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} - EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso - run: | - if [[ ! -f "${GENERATED_ISO}" ]]; then - echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" - exit 1 - fi - if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then - mkdir -p "$(dirname "${EXPECTED_ISO}")" - mv "${GENERATED_ISO}" "${EXPECTED_ISO}" - fi - - - name: Display checksum - shell: bash - run: | - set -o pipefail - iso_path="output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" - checksum_path="${iso_path}-CHECKSUM" - sha256sum "${iso_path}" | tee "${checksum_path}" - { - echo "# ISO Checksum (SHA256)" - echo - echo "ISO: $(basename "${iso_path}")" - echo - echo '```' - cat "${checksum_path}" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - - - name: Move ISO to upload directory - id: upload-directory - shell: bash - run: | - iso_upload_dir="${{ github.workspace }}/output/upload" - iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" - iso_name="$(basename "${iso_path}")" - - mkdir -p "${iso_upload_dir}" - mv "${iso_path}" "${iso_upload_dir}/" - ( - cd "${iso_upload_dir}" - sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" - ) - echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" - - - name: Upload ISO and checksum to R2 - if: github.event_name == 'workflow_dispatch' && (github.ref_name == 'main' || github.ref_name == 'testing') - shell: bash - 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_REGION: auto - RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} - SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} - run: | - sudo apt-get update - sudo apt-get install -y rclone - rclone copy "$SOURCE_DIR" R2:bazzite diff --git a/.github/workflows/build-live-iso.yml b/.github/workflows/build-live-iso.yml new file mode 100644 index 0000000..a364f6c --- /dev/null +++ b/.github/workflows/build-live-iso.yml @@ -0,0 +1,167 @@ +name: Build Live ISOs + +on: + workflow_dispatch: + inputs: + image_tag: + description: "AeroCore image tag to install" + required: false + default: latest + type: string + workflow_call: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-live-iso: + name: Build KDE live ISO + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + + env: + IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} + IMAGE_NAME: ${{ vars.IMAGE_NAME || github.event.repository.name }} + IMAGE_TAG: ${{ inputs.image_tag || 'latest' }} + ISO_FILE_TAG: ${{ github.ref_name == 'testing' && 'testing' || (inputs.image_tag || 'latest') }} + # Keep these aligned with the Fedora major used by the target bazzite-deck base image. + LIVE_BASE_IMAGE: quay.io/fedora/fedora-kinoite:44 + FEDORA_VERSION: "44" + OSTREE_IMAGE_REF: ${{ vars.OSTREE_IMAGE_REF }} + + steps: + - name: Maximize build space + uses: ublue-os/remove-unwanted-software@cc0becac701cf642c8f0a6613bbdaf5dc36b259e # v9 + with: + remove-codeql: true + + - name: Mount container storage BTRFS loopback + run: | + sudo truncate -s 70G /mnt/podman-storage.img + sudo mkfs.btrfs -f /mnt/podman-storage.img + sudo podman system reset --force + sudo systemctl stop podman.service + sudo mount -o compress-force=zstd:2 /mnt/podman-storage.img /var/lib/containers/storage + sudo systemctl start podman.service + + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + + - name: Prepare image references + run: | + image_name="${IMAGE_NAME,,}" + image_registry="${IMAGE_REGISTRY,,}" + echo "IMAGE_NAME=${image_name,,}" >> "$GITHUB_ENV" + echo "IMAGE_REGISTRY=${image_registry}" >> "$GITHUB_ENV" + + - name: Login to GHCR + run: | + echo '${{ secrets.GITHUB_TOKEN }}' | sudo podman login ghcr.io \ + --username '${{ github.actor }}' --password-stdin + + - name: Pull AeroCore install image + run: | + sudo podman pull "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" + + - name: Build installer ISO payload + run: | + mkdir -p output + ostree_image_ref="${OSTREE_IMAGE_REF:-ostree-image-signed:docker://${IMAGE_REGISTRY}/${IMAGE_NAME}}" + install_image_ref="${ostree_image_ref#ostree-image-signed:docker://}" + install_image_ref="${install_image_ref#ostree-unverified-registry:docker://}" + install_image_ref="${install_image_ref#docker://}" + sudo podman tag \ + "${IMAGE_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" \ + "${install_image_ref}:${IMAGE_TAG}" + sudo podman save \ + --format oci-archive \ + --output output/install-payload.oci \ + "${install_image_ref}:${IMAGE_TAG}" + + sudo podman build \ + --cap-add sys_admin \ + --security-opt label=disable \ + --build-arg "BASE_IMAGE=${LIVE_BASE_IMAGE}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD=${install_image_ref}:${IMAGE_TAG}" \ + --build-arg "INSTALL_IMAGE_PAYLOAD_ARCHIVE=/install-payload.oci" \ + --build-arg "INSTALL_IMAGE_TAG=${IMAGE_TAG}" \ + --build-arg "OSTREE_IMAGE_REF=${ostree_image_ref}" \ + --tag localhost/aerocore-os-installer:latest \ + --file installer/Containerfile \ + . + + - name: Build ISO + id: build + uses: Zeglius/titanoboa@7737f4748458252ac827dca14b3d6dd09298472a # revamp-pr + with: + image-ref: localhost/aerocore-os-installer:latest + iso-dest: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso + + - name: Normalize ISO output path + shell: bash + env: + GENERATED_ISO: ${{ steps.build.outputs.iso-dest }} + EXPECTED_ISO: ${{ github.workspace }}/output/aerocore-os-${{ env.ISO_FILE_TAG }}-live-amd64.iso + run: | + if [[ ! -f "${GENERATED_ISO}" ]]; then + echo "::error::Generated ISO does not exist at ${GENERATED_ISO}" + exit 1 + fi + if [[ "${GENERATED_ISO}" != "${EXPECTED_ISO}" ]]; then + mkdir -p "$(dirname "${EXPECTED_ISO}")" + mv "${GENERATED_ISO}" "${EXPECTED_ISO}" + fi + + - name: Display checksum + shell: bash + run: | + set -o pipefail + iso_path="output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" + checksum_path="${iso_path}-CHECKSUM" + sha256sum "${iso_path}" | tee "${checksum_path}" + { + echo "# ISO Checksum (SHA256)" + echo + echo "ISO: $(basename "${iso_path}")" + echo + echo '```' + cat "${checksum_path}" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + + - name: Move ISO to upload directory + id: upload-directory + shell: bash + run: | + iso_upload_dir="${{ github.workspace }}/output/upload" + iso_path="${{ github.workspace }}/output/aerocore-os-${ISO_FILE_TAG}-live-amd64.iso" + iso_name="$(basename "${iso_path}")" + + mkdir -p "${iso_upload_dir}" + mv "${iso_path}" "${iso_upload_dir}/" + ( + cd "${iso_upload_dir}" + sha256sum "${iso_name}" | tee "${iso_name}-CHECKSUM" + ) + echo "iso-upload-dir=${iso_upload_dir}" >> "$GITHUB_OUTPUT" + + - name: Upload ISO and checksum to R2 + if: github.event_name == 'workflow_dispatch' && (github.ref_name == 'main' || github.ref_name == 'testing') + shell: bash + 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_REGION: auto + RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} + SOURCE_DIR: ${{ steps.upload-directory.outputs.iso-upload-dir }} + run: | + sudo apt-get update + sudo apt-get install -y rclone + rclone copy "$SOURCE_DIR" R2:bazzite -- cgit v1.2.3 From 9fcb843f225e9618155a6b9228006859e91f7f0b Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 23 Sep 2026 17:27:25 +0800 Subject: fix: correct release commits section --- .github/scripts/generate_changelog.py | 53 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to '.github') diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 0bcf369..2486fb6 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -161,6 +161,25 @@ def upstream_release_commit(tag: str) -> str | None: return None +def upstream_compare_commits(start_revision: str | None, end_revision: str | None) -> list[tuple[str, str, str]]: + if not start_revision or not end_revision or start_revision == end_revision: + return [] + request = urllib.request.Request( + f"https://api.github.com/repos/ublue-os/bazzite/compare/{start_revision}...{end_revision}", + headers={"Accept": "application/vnd.github+json", "User-Agent": "AeroCore-OS-release-notes"}, + ) + with urllib.request.urlopen(request, timeout=60) as response: + compare = json.load(response) + return [ + ( + item["sha"], + item["commit"]["message"].splitlines()[0], + item["commit"].get("author", {}).get("name", "Unknown"), + ) + for item in compare.get("commits", []) + ] + + def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--image", required=True, help="registry/repository without tag") @@ -201,22 +220,8 @@ def main() -> None: current_base_tag = base_image.rpartition(":")[2] if base_image else "" start_revision = upstream_release_commit(previous_base_tag) if previous_base_tag else None end_revision = upstream_release_commit(current_base_tag) if current_base_tag else None - upstream_commits = [] - if start_revision and end_revision and start_revision != end_revision: - request = urllib.request.Request( - f"https://api.github.com/repos/ublue-os/bazzite/compare/{start_revision}...{end_revision}", - headers={"Accept": "application/vnd.github+json", "User-Agent": "AeroCore-OS-release-notes"}, - ) - with urllib.request.urlopen(request, timeout=60) as response: - compare = json.load(response) - upstream_commits = [ - ( - item["sha"], - item["commit"]["message"].splitlines()[0], - item["commit"]["author"].get("name", "Unknown"), - ) - for item in compare.get("commits", []) - ] + upstream_commits = upstream_compare_commits(start_revision, end_revision) + upstream_range_available = bool(start_revision and end_revision) start_revision = previous_info.get("Labels", {}).get("org.opencontainers.image.revision") end_revision = current_info.get("Labels", {}).get("org.opencontainers.image.revision") @@ -255,15 +260,19 @@ def main() -> None: lines += ["", "### Commits", "", "| Hash | Subject | Author |", "| --- | --- | --- |"] if upstream_commits: - lines.append("| | **Upstream Bazzite** | | |") + lines.append("| **Upstream Bazzite** | | |") for commit_hash, subject, author in upstream_commits: - lines.append(f"| | **[{commit_hash[:7]}](https://github.com/ublue-os/bazzite/commit/{commit_hash})** | {subject} | {author} |") + lines.append(f"| [{commit_hash[:7]}](https://github.com/ublue-os/bazzite/commit/{commit_hash}) | {subject} | {author} |") + elif upstream_range_available: + lines.append("| **Upstream Bazzite** | No commits between the selected base versions | — |") + else: + lines.append("| **Upstream Bazzite** | Commit range unavailable (previous image may predate base image metadata) | — |") if aerocore_commits: - lines.append("| | **AeroCore OS** | | |") + lines.append("| **AeroCore OS** | | |") for commit_hash, subject, author in aerocore_commits: - lines.append(f"| | **[{commit_hash[:7]}](https://github.com/{args.repository}/commit/{commit_hash})** | {subject} | {author} |") - if not upstream_commits and not aerocore_commits: - lines.append("| — | No commit range available | — |") + lines.append(f"| [{commit_hash[:7]}](https://github.com/{args.repository}/commit/{commit_hash}) | {subject} | {author} |") + if not aerocore_commits: + lines.append("| **AeroCore OS** | No commits between the selected image versions | — |") lines += ["", "### All Images", "", "| | Name | Previous | New |", "| --- | --- | --- | --- |"] if previous and previous_packages is None: -- cgit v1.2.3 From f7c095592475d22e6d1d263b988c8a7974882521 Mon Sep 17 00:00:00 2001 From: tranch Date: Wed, 14 Oct 2026 17:03:33 +0800 Subject: chore: align testing with Bazzite 44.20261012 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to '.github') diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bb6f79..5ec0da4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ env: IMAGE_LOGO_URL: ${{ vars.IMAGE_LOGO_URL || 'https://avatars.githubusercontent.com/u/120078124?s=200&v=4' }} DEFAULT_TAG: ${{ vars.DEFAULT_TAG || 'stable' }} BIB_IMAGE: ${{ vars.BIB_IMAGE || 'quay.io/centos-bootc/bootc-image-builder:latest' }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20261012' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} @@ -95,7 +95,7 @@ jobs: - name: Generate Version and Tags id: gen-version env: - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20261012' }} run: | set -euo pipefail @@ -162,7 +162,7 @@ jobs: id: build-image env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20260921' }} + BASE_IMAGE: ${{ vars.BASE_IMAGE || 'ghcr.io/ublue-os/bazzite-deck:stable-44.20261012' }} FLATPAK_REMOTE_URL: ${{ vars.FLATPAK_REMOTE_URL }} HOMEBREW_BOTTLE_DOMAIN: ${{ vars.HOMEBREW_BOTTLE_DOMAIN }} HOMEBREW_API_DOMAIN: ${{ vars.HOMEBREW_API_DOMAIN }} -- cgit v1.2.3 From 0891c70f559c7d23a306290334388853ff317181 Mon Sep 17 00:00:00 2001 From: tranch Date: Fri, 16 Oct 2026 01:18:48 +0800 Subject: fix: tolerate unavailable changelog revisions --- .github/scripts/generate_changelog.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to '.github') diff --git a/.github/scripts/generate_changelog.py b/.github/scripts/generate_changelog.py index 2486fb6..4c5d7c1 100644 --- a/.github/scripts/generate_changelog.py +++ b/.github/scripts/generate_changelog.py @@ -225,16 +225,23 @@ def main() -> None: start_revision = previous_info.get("Labels", {}).get("org.opencontainers.image.revision") end_revision = current_info.get("Labels", {}).get("org.opencontainers.image.revision") - aerocore_commits = ( - [ - (item.split("\t", 2)[0], item.split("\t", 2)[1], item.split("\t", 2)[2]) - for item in run( - "git", "log", "--format=%H%x09%s%x09%an", f"{start_revision}..{end_revision}" - ).splitlines() - ] - if start_revision and end_revision and start_revision != end_revision - else [] - ) + aerocore_commits: list[tuple[str, str, str]] = [] + if start_revision and end_revision and start_revision != end_revision: + try: + aerocore_commits = [ + (item.split("\t", 2)[0], item.split("\t", 2)[1], item.split("\t", 2)[2]) + for item in run( + "git", "log", "--format=%H%x09%s%x09%an", f"{start_revision}..{end_revision}" + ).splitlines() + ] + except subprocess.CalledProcessError as error: + # Release metadata can point to revisions outside this checkout's + # history after histories are joined or rewritten. Keep the package + # and upstream changelog sections and omit only AeroCore commits. + print( + "Warning: unable to determine AeroCore commit range " + f"{start_revision}..{end_revision}: {error}" + ) lines = [args.handwritten.strip() or f"This is an automatically generated changelog for release `{args.current}`.", ""] if base_image: -- cgit v1.2.3