ci(flatpak): restore previous builder cache and skip src-only PRs (#825)
The builder action restore-keys is `flatpak-builder-${arch}`. Our key
was `flatpak-builder-${hash}`, which the action stores as
`flatpak-builder-${hash}-x86_64`. That does not start with
`flatpak-builder-x86_64`, so a packaging hash change (a lock refresh,
or merging one) discarded the whole .flatpak-builder cache and
recompiled numpy and pywhispercpp from source, ~18 min instead of ~4.
Put ${{ matrix.arch }} in the key first so the fallback matches. Then
flatpak-builder skips unchanged modules and only rebuilds what the
hash change actually touched.
PRs no longer watch src/**. python-test already covers those, and the
expensive compile does not. push to main still does, so a sandbox
install break fails the default branch.
This commit is contained in:
@@ -16,7 +16,10 @@ on:
|
||||
branches: [ main, master ]
|
||||
paths:
|
||||
- 'packaging/flatpak/**'
|
||||
- 'src/**'
|
||||
# src/** is push-only. A text-injection PR already runs python-test;
|
||||
# the Flatpak job's cost is compiling numpy and pywhispercpp from
|
||||
# source, which those PRs do not change. main still builds src-only
|
||||
# pushes so a sandbox install break fails the default branch.
|
||||
- 'pyproject.toml'
|
||||
# The dependency manifest is generated from the hash-pinned export, so a
|
||||
# lock refresh moves what this build ships. Without this, `just lock`
|
||||
@@ -67,10 +70,12 @@ jobs:
|
||||
with:
|
||||
bundle: vocalinux-${{ matrix.arch }}.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
# Stable key so .flatpak-builder cache restores across commits.
|
||||
# The action appends -${arch} and restore-keys is
|
||||
# `flatpak-builder-${arch}`, so the key has to start with that
|
||||
# prefix. Putting the packaging hash first made every lock
|
||||
# refresh a full rebuild (numpy + pywhispercpp from source).
|
||||
# github.sha in the key forced a full rebuild every run.
|
||||
# Arch is appended automatically by the action.
|
||||
cache-key: flatpak-builder-${{ hashFiles('packaging/flatpak/**') }}
|
||||
cache-key: flatpak-builder-${{ matrix.arch }}-${{ hashFiles('packaging/flatpak/**') }}
|
||||
arch: ${{ matrix.arch }}
|
||||
artifact-name: vocalinux-flatpak-${{ matrix.arch }}
|
||||
# Flathub mirrors screenshots at submission time; mirror locally so the
|
||||
|
||||
@@ -275,7 +275,9 @@ jobs:
|
||||
with:
|
||||
bundle: Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
cache-key: flatpak-builder-${{ hashFiles('packaging/flatpak/**') }}
|
||||
# Same prefix rule as flatpak.yml: restore-keys is
|
||||
# `flatpak-builder-${arch}`. The action appends -${arch} again.
|
||||
cache-key: flatpak-builder-x86_64-${{ hashFiles('packaging/flatpak/**') }}
|
||||
arch: x86_64
|
||||
# Pinned actions/upload-artifact below, same digest as AppImage.
|
||||
upload-artifact: false
|
||||
@@ -310,7 +312,7 @@ jobs:
|
||||
with:
|
||||
bundle: Vocalinux-${{ steps.get_version.outputs.VERSION }}-aarch64.flatpak
|
||||
manifest-path: packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
cache-key: flatpak-builder-${{ hashFiles('packaging/flatpak/**') }}
|
||||
cache-key: flatpak-builder-aarch64-${{ hashFiles('packaging/flatpak/**') }}
|
||||
arch: aarch64
|
||||
upload-artifact: false
|
||||
mirror-screenshots-url: https://dl.flathub.org/media
|
||||
|
||||
@@ -242,6 +242,17 @@ def test_no_source_is_pinned_to_one_python_abi(source: dict[str, str]) -> None:
|
||||
)
|
||||
|
||||
|
||||
def _on_event_block(event: str) -> str:
|
||||
"""The body of one `on:` event, up to the next same-indent key."""
|
||||
match = re.search(
|
||||
rf"^ {re.escape(event)}:\n(.*?)(?=^ [a-z_]+:|\Z)",
|
||||
WORKFLOW.read_text(encoding="utf-8"),
|
||||
re.M | re.S,
|
||||
)
|
||||
assert match, f"flatpak.yml has no on.{event} block"
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def test_a_lock_refresh_reaches_the_flatpak_build() -> None:
|
||||
"""The manifest is generated from requirements/, so a change there changes
|
||||
what the Flatpak ships. Without the path filter, `just lock` could move
|
||||
@@ -251,3 +262,27 @@ def test_a_lock_refresh_reaches_the_flatpak_build() -> None:
|
||||
"flatpak.yml does not watch requirements/**, so a lock refresh changes"
|
||||
" what the Flatpak builds and runs no build"
|
||||
)
|
||||
|
||||
|
||||
def test_prs_skip_the_flatpak_build_when_only_src_changed() -> None:
|
||||
"""numpy and pywhispercpp compile from source. A text-injection PR does
|
||||
not need that. push to main still watches src/** so a sandbox install
|
||||
break still fails the default branch."""
|
||||
assert "'src/**'" not in _on_event_block("pull_request")
|
||||
assert "'src/**'" in _on_event_block("push")
|
||||
|
||||
|
||||
def test_builder_cache_key_is_a_prefix_the_action_can_restore() -> None:
|
||||
"""The action restore-keys is `flatpak-builder-${arch}`.
|
||||
|
||||
cache-key is passed through as `${cache-key}-${arch}`. A key of
|
||||
`flatpak-builder-${hash}` becomes `flatpak-builder-${hash}-x86_64`,
|
||||
which does not start with `flatpak-builder-x86_64`, so a packaging
|
||||
hash change discarded the previous .flatpak-builder cache and
|
||||
recompiled numpy and pywhispercpp from scratch (~18 min). Putting
|
||||
`${{ matrix.arch }}` in the key first makes the fallback match.
|
||||
"""
|
||||
assert (
|
||||
"cache-key: flatpak-builder-${{ matrix.arch }}-"
|
||||
"${{ hashFiles('packaging/flatpak/**') }}" in WORKFLOW.read_text(encoding="utf-8")
|
||||
)
|
||||
|
||||
@@ -202,6 +202,13 @@ def test_flatpak_release_jobs_reuse_ci_builder_pins():
|
||||
assert "options: --privileged" in block, f"{name} is not a privileged container"
|
||||
assert _FLATPAK_BUILDER in block, f"{name} does not use the pinned builder action"
|
||||
assert f"arch: {arch}" in block
|
||||
assert (
|
||||
f"cache-key: flatpak-builder-{arch}-${{{{ hashFiles('packaging/flatpak/**') }}}}"
|
||||
in block
|
||||
), (
|
||||
f"{name} cache-key must start with flatpak-builder-{arch} so the "
|
||||
"action's restore-keys prefix matches after it appends -${arch}"
|
||||
)
|
||||
assert f"runs-on: {runner}" in block
|
||||
assert f"Vocalinux-${{{{ steps.get_version.outputs.VERSION }}}}-{arch}.flatpak" in block
|
||||
assert "actions/upload-artifact" in block, f"{name} does not upload a workflow artifact"
|
||||
|
||||
Reference in New Issue
Block a user