diff --git a/.github/renovate.json b/.github/renovate.json index bc9a6b3bb3..1fb1ed0ccf 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -145,19 +145,6 @@ } ], "customManagers": [ - { - "customType": "regex", - "description": "Mirror gradle-wrapper.properties bumps into the vendored Gradle distribution URL in the verify-flatpak offline manifest (see PRs #6777/#6782, where a wrapper bump without this file broke both build-flatpak arches). Shares depName 'gradle' with the gradle-wrapper manager so both files update in the same Renovate branch/PR. The sha256 line below the URL cannot be auto-updated (the gradle-version datasource has no digest support and the hosted app disallows postUpgradeTasks); the fail-fast guard in verify-flatpak.yml's generate-sources job holds that PR red until the sha256 is copied from distributionSha256Sum.", - "managerFilePatterns": [ - "/^scripts/verify-flatpak/desktop-offline\\.yaml$/" - ], - "matchStrings": [ - "services\\.gradle\\.org/distributions/gradle-(?\\d+(?:\\.\\d+)*)-bin\\.zip" - ], - "depNameTemplate": "gradle", - "datasourceTemplate": "gradle-version", - "versioningTemplate": "gradle" - }, { "customType": "regex", "description": "ktlint's version is a bare [versions] entry that only Spotless reads, so the gradle manager cannot tie it to an artifact.", diff --git a/.github/workflows/verify-flatpak.yml b/.github/workflows/verify-flatpak.yml index ad6200578e..6cc423d810 100644 --- a/.github/workflows/verify-flatpak.yml +++ b/.github/workflows/verify-flatpak.yml @@ -8,8 +8,8 @@ on: paths: - 'scripts/verify-flatpak/**' - '.github/workflows/verify-flatpak.yml' - # Post-merge only for what the check itself depends on. The offline manifest pins the - # Gradle distribution apart from the wrapper, so a wrapper bump is checked on merge. + # Post-merge only for what the check itself depends on. The offline build vendors the + # wrapper's Gradle distribution, so a wrapper bump is checked on merge. push: branches: [ main ] paths: @@ -49,28 +49,6 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - # Renovate mirrors wrapper bumps into the manifest's distribution URL but cannot - # rewrite its sha256, so on a wrapper bump this drift is expected: fail here in - # seconds instead of ~15 minutes into the build ("Verification of Gradle - # distribution failed!", see #6777/#6782). - - name: Check vendored Gradle dist matches the wrapper - run: | - props=gradle/wrapper/gradle-wrapper.properties - manifest=scripts/verify-flatpak/desktop-offline.yaml - wrapper_dist=$(grep '^distributionUrl=' "$props" | sed 's|.*/||' || true) - wrapper_sha=$(grep '^distributionSha256Sum=' "$props" | cut -d= -f2 || true) - manifest_dist=$(grep -o 'gradle-[0-9][^/]*\.zip' "$manifest" || true) - manifest_sha=$(awk '/url:.*services\.gradle\.org\/distributions\//{getline; sub(/^[[:space:]]*sha256:[[:space:]]*/, ""); print}' "$manifest") - if [ -z "$wrapper_dist" ] || [ -z "$wrapper_sha" ]; then - echo "::error file=$props::Could not parse distributionUrl/distributionSha256Sum from $props; the guard in verify-flatpak.yml needs updating." - exit 1 - fi - if [ "$wrapper_dist" != "$manifest_dist" ] || [ "$wrapper_sha" != "$manifest_sha" ]; then - echo "::error file=$manifest::Vendored Gradle dist is out of sync: $manifest pins '$manifest_dist' (sha256 '$manifest_sha') but $props pins '$wrapper_dist' (sha256 '$wrapper_sha'). Update the url and sha256 in $manifest; the correct sha256 is distributionSha256Sum in $props." - exit 1 - fi - echo "OK: $manifest vendors $wrapper_dist, matching $props" - - uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6 with: distribution: temurin @@ -122,6 +100,9 @@ jobs: run: | cp scripts/verify-flatpak/desktop-offline.yaml \ "$RUNNER_TEMP/org.meshtastic.MeshtasticDesktop/org.meshtastic.MeshtasticDesktop.yaml" + python3 scripts/verify-flatpak/bump-flathub-manifest.py --gradle-only \ + "$RUNNER_TEMP/org.meshtastic.MeshtasticDesktop/org.meshtastic.MeshtasticDesktop.yaml" \ + gradle/wrapper/gradle-wrapper.properties cp flatpak-sources.json \ "$RUNNER_TEMP/org.meshtastic.MeshtasticDesktop/flatpak-sources.json" rsync -a --delete \ diff --git a/scripts/verify-flatpak/README.md b/scripts/verify-flatpak/README.md index 0253f42808..36252757dd 100644 --- a/scripts/verify-flatpak/README.md +++ b/scripts/verify-flatpak/README.md @@ -78,7 +78,9 @@ executing the Gradle build, or run the full script on a Linux host. - `verify.sh` — entry point. Idempotent: re-running just re-syncs the overlay and re-runs flatpak-builder. - `desktop-offline.yaml` — patched manifest. Kept in sync manually with the upstream packaging; diff against `https://raw.githubusercontent.com/flathub/org.meshtastic.MeshtasticDesktop/master/org.meshtastic.MeshtasticDesktop.yaml` - if upstream changes something material. + if upstream changes something material. Its Gradle zip is a placeholder; `verify.sh` and + `verify-flatpak.yml` fill it from `gradle/wrapper/gradle-wrapper.properties`. - `bump-flathub-manifest.py` - points the upstream manifest at a release: the source tag and commit, and the Gradle zip the tag's wrapper pins. `promote.yml`'s `update-flathub` job runs it on every production promotion, then commits the release's `flatpak-sources.json` beside it. + `--gradle-only` rewrites just the Gradle zip, for the overlay. diff --git a/scripts/verify-flatpak/bump-flathub-manifest.py b/scripts/verify-flatpak/bump-flathub-manifest.py index e346d51ad8..499af29c21 100755 --- a/scripts/verify-flatpak/bump-flathub-manifest.py +++ b/scripts/verify-flatpak/bump-flathub-manifest.py @@ -2,9 +2,11 @@ """Point the Flathub manifest at a release: the source tag and commit, and the Gradle zip. Usage: bump-flathub-manifest.py + bump-flathub-manifest.py --gradle-only The Gradle distribution URL and sha256 come from the tag's own wrapper properties, since the -offline build can only run the Gradle version that tag pins. Each field is rewritten in +offline build can only run the Gradle version that tag pins. --gradle-only rewrites just the +Gradle zip, which is how the verify-flatpak overlay gets the working tree's wrapper. Each field is rewritten in place, so comments and layout survive. Any field that does not match exactly once fails the run instead of guessing, and the manifest is then bumped by hand. """ @@ -49,22 +51,29 @@ def replace_once(pattern: re.Pattern, value_a: str, value_b: str, text: str, wha def main() -> None: - if len(sys.argv) != 5: + args = sys.argv[1:] + gradle_only = args[:1] == ["--gradle-only"] + if gradle_only and len(args) == 3: + manifest, wrapper = args[1:] + elif not gradle_only and len(args) == 4: + manifest, tag, commit, wrapper = args + if not re.fullmatch(r"v\d+\.\d+\.\d+", tag): + sys.exit(f"'{tag}' is not a production tag (vX.Y.Z)") + if not re.fullmatch(r"[0-9a-f]{40}", commit): + sys.exit(f"'{commit}' is not a full commit sha") + else: sys.exit(__doc__) - manifest, tag, commit, wrapper = sys.argv[1:] - if not re.fullmatch(r"v\d+\.\d+\.\d+", tag): - sys.exit(f"'{tag}' is not a production tag (vX.Y.Z)") - if not re.fullmatch(r"[0-9a-f]{40}", commit): - sys.exit(f"'{commit}' is not a full commit sha") url, sha = wrapper_distribution(wrapper) with open(manifest, encoding="utf-8") as f: text = f.read() - text = replace_once(GIT_SOURCE, tag, commit, text, "Meshtastic-Android git source (url, tag, commit)") + if not gradle_only: + text = replace_once(GIT_SOURCE, tag, commit, text, "Meshtastic-Android git source (url, tag, commit)") text = replace_once(GRADLE_ZIP, url, sha, text, "Gradle distribution (url, sha256)") with open(manifest, "w", encoding="utf-8") as f: f.write(text) - print(f"{manifest}: {tag} at {commit}, {url.rsplit('/', 1)[-1]}") + zip_name = url.rsplit("/", 1)[-1] + print(f"{manifest}: {zip_name}" if gradle_only else f"{manifest}: {tag} at {commit}, {zip_name}") if __name__ == "__main__": diff --git a/scripts/verify-flatpak/desktop-offline.yaml b/scripts/verify-flatpak/desktop-offline.yaml index 882909dcfa..12a7285d73 100644 --- a/scripts/verify-flatpak/desktop-offline.yaml +++ b/scripts/verify-flatpak/desktop-offline.yaml @@ -97,12 +97,10 @@ modules: - type: dir path: meshtastic-android - type: file - # Must be the EXACT distribution from gradle-wrapper.properties (version AND -bin - # flavor); distributionSha256Sum verifies this file. Renovate bumps the version here - # alongside wrapper bumps (custom manager in renovate.json) but the sha256 must be - # copied from distributionSha256Sum by hand; CI fails fast on any mismatch. - url: https://services.gradle.org/distributions/gradle-9.8.2-bin.zip - sha256: 21bd5da2de49b642904077f38c0efdc7778e92b3ed0889392dca61b97e389607 + # Placeholder: verify.sh and verify-flatpak.yml stamp the url and sha256 from + # gradle-wrapper.properties into their copy (bump-flathub-manifest.py --gradle-only). + url: https://services.gradle.org/distributions/gradle-from-wrapper-bin.zip + sha256: 0000000000000000000000000000000000000000000000000000000000000000 dest: "gradle/wrapper" dest-filename: "gradle-bin.zip" - flatpak-sources.json diff --git a/scripts/verify-flatpak/verify.sh b/scripts/verify-flatpak/verify.sh index 1dc55d001b..db76ef7cd8 100755 --- a/scripts/verify-flatpak/verify.sh +++ b/scripts/verify-flatpak/verify.sh @@ -107,6 +107,9 @@ fi # flatpak-sources.json = the artifact we're validating step "Wiring overlay manifest + our flatpak-sources.json" cp "$OVERLAY" "$WORK/org.meshtastic.MeshtasticDesktop/org.meshtastic.MeshtasticDesktop.yaml" +python3 "$REPO_ROOT/scripts/verify-flatpak/bump-flathub-manifest.py" --gradle-only \ + "$WORK/org.meshtastic.MeshtasticDesktop/org.meshtastic.MeshtasticDesktop.yaml" \ + "$REPO_ROOT/gradle/wrapper/gradle-wrapper.properties" cp "$SOURCES_JSON" "$WORK/org.meshtastic.MeshtasticDesktop/flatpak-sources.json" if [[ $REBUILD_ONLY -eq 0 ]]; then