Repository navigation
ci: upstream compatibility alerts and auto-publish to pub.dev - #30
Merged
Merged
Conversation
Upstream compatibility (daily + manual): for each package, test the newest releases within our constraints, and the newest upstream majors when pub outdated reports any, with the same checks as the CI package job, on the newest Flutter stable. When pub upgrade --major-versions cannot reach a new major, `pub add name:^latest` forces it, so the leg tests the new major or reports what blocks it instead of passing on the old one. One issue per package under the upstream-compat label, touched only when its fingerprint changes and closed once the package passes again. Release: after CI succeeds on a push to main, packages whose pubspec version is not on pub.dev (and tops CHANGELOG.md, and is newer than pub.dev) are re-verified with analyze, tests and publish --dry-run, tagged <package>-v<version>, and handed to Publish via workflow_dispatch, because a GITHUB_TOKEN tag push does not trigger workflows. Publish: dart-lang/setup-dart's reusable publish workflow (OIDC) in the pub.dev environment, after checking the tag against pubspec and changelog.
Upstream compatibility: - An issue the workflow closed itself (package passing again) is marked auto-closed and never silences a later identical finding; only a hand-closed issue does. A hand-reopened auto-closed issue loses the marker. - Fingerprints and step names count upstream releases by caret line, so an upstream patch or minor no longer edits open issues or reopens hand-closed ones; a new major still does. - A resolve step that fails with pub's network errors makes the check exit 4 with no report instead of filing a `broken` issue. - outdated rows need a newer caret line, not just any newer release. Release and publish: - Release dispatched by hand only runs on main. - An existing tag is re-dispatched only when it points at the verified commit and no Publish run for it is still active; a tag on an older commit fails the run. - Publish refuses a tag whose commit is not on main. - release_plan orders build metadata as pub does and reports tag SHAs (peeled for annotated tags). - Corrected the description of dart-lang's reusable publish workflow.
…g test
Release:
- Split the release job. `verify` runs pub get, analyze, tests and the
publish dry-run with a read-only token, no persisted credentials and no
shared Flutter/pub cache; `tag` holds contents/actions write and runs no
package code (no checkout). A per-package artifact marker carries the
verified commit across, so one package failing does not hold back the
others in the same merge.
- The active-Publish check now runs before every dispatch, not only for
existing tags.
- matrix and step values reach run: blocks through env, not ${{ }}.
Publish:
- The on-main check uses `git merge-base --is-ancestor` against a full
fetch instead of the compare API.
- `resolve` skips publishing, green, when pub.dev already has the version,
so a duplicate dispatch or a re-run cannot fail at upload.
- dart-lang's reusable publish workflow is pinned to 6afc89d (v1). Its
only inputs are environment and working-directory, so Flutter cannot be
pinned to CI's version there.
Upstream compatibility:
- A dependency counts as held back only when our declared constraint
excludes its newest release. SDK-pinned packages such as meta, and
dependencies another package caps, no longer produce lag findings.
- pub's exit code 69 (package server unavailable) is a tooling failure,
alongside the existing network-error wording.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two automations for this repo: daily alerts when a newer upstream release or a new Flutter stable breaks or excludes one of our plugins, and automatic publishing to pub.dev when a version bump lands on
main.Upstream compatibility (
upstream-compat.yml)Runs daily at 05:17 UTC. It can also be started by hand, with optional inputs to check a single package, pick a Flutter version, or do a dry run. It always uses the newest Flutter stable, unlike CI, which is pinned.
For each package,
.github/scripts/upstream_check.pyruns two passes on a scratch copy ofpackages/:flutter pub upgrade, the newest releases within our constraints.pub outdatedshows a newer major outside our constraint. It runspub upgrade --major-versionson our direct dependencies. That command quietly stays on the old major when something else blocks the new one, so for anything left behind the pass also runspub add <dep>:^<latest>. That way the pass either tests the new major for real or records pub's explanation of what is blocking it.Each pass then runs the same checks as the CI package job: analyze
libandtest,flutter test, and resolve and analyze the example. Every package gets one of these results:brokenmajor-breakslagok.github/scripts/upstream_issues.pykeeps one issue per package (Upstream compatibility: <package>, labelupstream-compat). The issue body carries a hidden fingerprint of the finding:meta, and dependencies another package caps, don't produce findings.Expect a batch of firebase issues on the first run
A local run on Flutter 3.47.9 found that
firebase_auth_tvoscan't move tofirebase_auth7.0.1. That version needsfirebase_core ^5.1.0, butfirebase_core_tvospins^4.13.0. Every package that depends onfirebase_core_tvoswill probably report the samemajor-breakson the first run, so expect several issues at once. They all point to the same fix: portfirebase_core_tvosto firebase_core 5. In the same run,shared_preferences_tvosandurl_launcher_tvoscame backok.Auto-publish (
release.yml→publish.yml)release.ymlruns after CI succeeds on a push tomain, or when started by hand to retry..github/scripts/release_plan.pypicks every package whose pubspec version isn't on pub.dev yet. Such a version must also:##heading inCHANGELOG.md, andIf either check fails, that package isn't released and the run ends red. Healthy packages in the same merge still go out.
Each release candidate goes through two jobs:
pub get, analyze, tests andflutter pub publish --dry-runon that exact commit. Because this runs third-party code, it gets a read-only token, no credentials persisted in.git/config, and no shared Flutter/pub cache.contents,actions) and runs no package code (no checkout). It creates the tag<package>-v<version>and startspublish.ymlon that tag, but only for packages whose verify passed. One failing package doesn't hold back the others.Why the release workflow starts the publish workflow itself: a tag created with
GITHUB_TOKENdoesn't triggeron: pushworkflows, butGITHUB_TOKENis allowed to start aworkflow_dispatchrun. pub.dev accepts publishing from aworkflow_dispatchrun on a tag ref when that event is enabled for the package. So no PAT or GitHub App is needed. Pushing a tag by hand also triggerspublish.ymldirectly.Started by hand, Release runs only on
main. No Publish is dispatched while one for the same tag is still queued, running or awaiting approval. A tag that already exists is re-dispatched only when it points at the commit just verified; a tag on an older commit fails the run with "bump the version or delete the tag".publish.ymlchecks that the tagged commit is an ancestor ofmain(git merge-base --is-ancestor) and that the tag matches the pubspec version and the changelog. If pub.dev already has that version, it stops there, green. Otherwise it calls dart-lang's reusablepublish.yml, pinned to commit6afc89d(v1), which publishes over OIDC in thepub.devenvironment. That workflow only acceptsenvironmentandworking-directory, so it installs the newest Flutter stable rather than CI's pinned version. Release's dry-run uses the pinned one.Today all 25 packages match their pub.dev versions, so merging this releases nothing.
pub.dev setup (manual, per package)
On
pub.dev/packages/<pkg>/admin→ Automated publishing → GitHub Actions:fluttertv/plugins<pkg>-v{{version}}pushandworkflow_dispatchevents. Withoutworkflow_dispatch, automatic releases fail at upload.pub.dev(recommended)On GitHub:
pub.dev, and under Deployment branches and tags choose Selected branches and tags with a tag rule*_tvos-v*. That way only release tags can deploy to it. Required reviewers are optional.github-actionsfrom creating*_tvos-v*tags.A brand-new package still needs its first version published by hand (
flutter pub publish), because pub.dev only allows automated publishing for packages that already exist.Also in this PR
.gitignore:__pycache__/Tested
release_plan.py: covered a version bump, a missing changelog entry, a version older than pub.dev, and an already-existing tag. Onmaintoday it finds nothing to release.gh. Also a--dry-runagainst this repo's real issues.check_repo.py --selfteststill passes.gh/flutterfor auto-close vs hand-close, reopened issues, patch vs major fingerprints, the network-error exit, build-metadata ordering and annotated-tag SHAs.meta-style SDK pins, ranges, carets below 1.0), exit 69, bot-closed vs hand-closed issues, plus the releaseTag statestep (tag on another commit, active Publish run) and the pub.dev already-published step run as-is with a stubbedghand the real pub.dev API.