From 525db204beaa27c787ed6a4b12f76daebffb6a59 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Wed, 13 May 2026 12:07:59 -0700 Subject: [PATCH 01/32] Create publish.yaml --- .github/workflows/publish.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 000000000..f857348fb --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,21 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ main ] + push: + # Match -v publish tags + tags: [ '[A-z0-9]+-v[0-9]+.[0-9]+.[0-9]+' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main + with: + sdk: beta + write-comments: false + permissions: + id-token: write + pull-requests: write From 6b53a7b864cf97a6cd9f4228397b79f0528c19b9 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Wed, 13 May 2026 15:29:49 -0700 Subject: [PATCH 02/32] - --- .github/workflows/post_summaries.yaml | 16 +++++++++++ .github/workflows/publish.yaml | 8 ++++-- CONTRIBUTING.md | 39 ++++++++++++++------------- 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/post_summaries.yaml diff --git a/.github/workflows/post_summaries.yaml b/.github/workflows/post_summaries.yaml new file mode 100644 index 000000000..cb937381c --- /dev/null +++ b/.github/workflows/post_summaries.yaml @@ -0,0 +1,16 @@ +# A CI configuration for pub-publish to write comments on PRs. + +name: Comment on the pull request + +on: + workflow_run: + workflows: + - Publish + types: + - completed + +jobs: + upload: + uses: dart-lang/ecosystem/.github/workflows/post_summaries.yaml@main + permissions: + pull-requests: write \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index f857348fb..921be8261 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -7,15 +7,19 @@ on: branches: [ main ] push: # Match -v publish tags - tags: [ '[A-z0-9]+-v[0-9]+.[0-9]+.[0-9]+' ] + tags: [ '[0-9A-z]+-v[0-9]+.[0-9]+.[0-9]+' ] jobs: publish: if: ${{ github.repository_owner == 'dart-lang' }} uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main with: - sdk: beta + # See https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose#options + sdk: beta # version of dart sdk to use for publishing + use-flutter: true write-comments: false + checkout_submodules: true + ignore-packages: "" permissions: id-token: write pull-requests: write diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e4e2ef32..a3298a8f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,7 +57,7 @@ of the front-line triage include: ### Periodic second-line triage -### Bi-weekly during the planning meeting +#### Bi-weekly during the planning meeting Check that existing issues are labeled and organized appropriately: @@ -66,7 +66,7 @@ Check that existing issues are labeled and organized appropriately: * Set a milestone to all [P0 and P1 issues][p0_p1_issues_without_milestone]. * Add all [projectless open issues][projectless_open_issues] to the "genui" project. -### Weekly during the planning meeting +#### Weekly during the planning meeting Triage issues ready for second-line review: @@ -103,13 +103,25 @@ own version number: * `genai_primitives` * `json_schema_builder` -"Releasing" consititutes manually publishing them all to [pub.dev] after the -pull request containing the version bump has passed CI. The packages must be -published by someone with permission to publish under the labs.flutter.org -owner. +## Publishing -Use the [release tool](tool/release/README.md) to help automate the process of -releasing a new version. +Publishing is happening automatically via GitHub actions. +See [Publishing automation][publishing-automation] for more details. + + + +## pubspec.lock files + +`pubspec.lock` files are not git ignored to make the bots faster. + +If you include `pubspec.lock` file to your PR, make sure to run `flutter pub upgrade`, +when your Flutter is latest at beta channel. + +## Internal information + +For Google-internal information see go/a2ui-internal. + + [pub.dev]: https://pub.dev [Semver]: https://semver.org/ @@ -124,14 +136,3 @@ releasing a new version. [P1]: https://github.com/flutter/genui/labels?q=P1 [P2]: https://github.com/flutter/genui/labels?q=P2 [P3]: https://github.com/flutter/genui/labels?q=P3 - -## pubspec.lock files - -`pubspec.lock` files are not git ignored to make the bots faster. - -If you include `pubspec.lock` file to your PR, make sure to run `flutter pub upgrade`, -when your Flutter is latest at beta channel. - -## Internal information - -For Google-internal information see go/a2ui-internal. From a726a97781127859808770449997ff0c1007aba1 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 11:21:50 -0700 Subject: [PATCH 03/32] Update publish.yaml --- .github/workflows/publish.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 921be8261..95de03c81 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -5,13 +5,14 @@ name: Publish on: pull_request: branches: [ main ] + types: [opened, synchronize, reopened, labeled, unlabeled] push: # Match -v publish tags - tags: [ '[0-9A-z]+-v[0-9]+.[0-9]+.[0-9]+' ] + tags: [ '[A-z0-9]+-v[0-9]+.[0-9]+.[0-9]+' ] jobs: publish: - if: ${{ github.repository_owner == 'dart-lang' }} + if: ${{ github.repository_owner == 'flutter' }} uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main with: # See https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose#options @@ -19,7 +20,6 @@ jobs: use-flutter: true write-comments: false checkout_submodules: true - ignore-packages: "" permissions: id-token: write pull-requests: write From 03af6a855e0cc3a16898f354ed61900dbed6e4aa Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 12:07:26 -0700 Subject: [PATCH 04/32] - --- CONTRIBUTING.md | 25 +++++-------------------- docs/contributing/README.md | 19 ++++++++----------- docs/contributing/publishing.md | 0 docs/contributing/pull_requests.md | 2 ++ 4 files changed, 15 insertions(+), 31 deletions(-) create mode 100644 docs/contributing/publishing.md create mode 100644 docs/contributing/pull_requests.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3298a8f3..0c61b5981 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,25 +1,10 @@ -# Contributing to GenUI for Flutter +# Contributing to this repository -## Guidelines +## Coding guidelines -Please follow [Flutter contributor guidelines][flutter_guidelines]. - -## Run Examples - -To run examples: - -1. Configure Firebase as described in [README.md][readme_md]. -2. Run `flutter run`. - -NOTE: For Google-internal projects see go/flutter-genui-internal. - -## Shell scripts - -To run a script in `tool/`, open the script in VSCode and press ⇧⌘B. - -## Detailed documentation for contributors - -See [docs/contributing.md](docs/contributing.md). +Please follow: + * [Flutter-wide contributor guidelines][flutter_guidelines]. + * [A2UI-specific guidelines](docs/contributing/README.md). ## Issue triage diff --git a/docs/contributing/README.md b/docs/contributing/README.md index 132385aff..3e37dc3aa 100644 --- a/docs/contributing/README.md +++ b/docs/contributing/README.md @@ -3,11 +3,14 @@ This folder provides guidance for contributors, targeted at both AI models and human developers. -## Index of Specifications +## Index of specifications This directory contains the following specifications: -- [Style Guide](styleguide.md) +- [Style guide](styleguide.md) +- [Design](design.md) +- [Pull requests](pull_requests.md) +- [Publishing](publishing.md) ## Note for AI models @@ -23,15 +26,9 @@ I have read and understood ./docs/contributing/README.md. 1. Documentation in the repository (all .md files) should be clear, consistent, concise and up-to-date. 2. Documentation should not contain details that are easy to infer from the code. 3. If code does not match the documentation, there should be TODO comments in the code to signal the discrepancy should be resolved. +4. For documentation use [sentence case for headings](https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings). -## Code reviews +## Shell scripts -Do not review pull requests when they are in draft state, unless explicitly requested by the author. +To run a script in `tool/`, open the script in VSCode and press ⇧⌘B. -## Key commands - -- **Run all checks and tests:** - - ```bash - ./tool/run_all_tests_and_fixes.sh - ``` diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/contributing/pull_requests.md b/docs/contributing/pull_requests.md new file mode 100644 index 000000000..a6fa81153 --- /dev/null +++ b/docs/contributing/pull_requests.md @@ -0,0 +1,2 @@ +# Authoring pull requests + From 052e2c492c60253bc518a954ae82365efb4a9fa4 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 12:12:53 -0700 Subject: [PATCH 05/32] - --- CONTRIBUTING.md | 36 ++------------------------------- docs/contributing/README.md | 36 ++++++++++++++++++++++++++++++++- docs/contributing/publishing.md | 5 +++++ 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0c61b5981..38a449727 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,44 +67,12 @@ Triage issues ready for second-line review: At the end of a triage session, the untriaged issue list should be as close to empty as possible. -## Versioning - -We use [Semver] for package versioning, although before 1.0.0, we will be -incrementing only the minor number for breaking changes and the patch number for -non-breaking changes. After 1.0.0, we will be using standard Semver, bumping the -major number for breaking changes. - -We release the following packages in lock step, -with the same version number, so when one is released, they are all released: - -* `genui` -* `genui_a2a` -* `genui_firebase_ai` -* `genui_google_generative_ui` - -These packages are released independently on their own schedule, with their -own version number: - -* `genai_primitives` -* `json_schema_builder` - -## Publishing - -Publishing is happening automatically via GitHub actions. -See [Publishing automation][publishing-automation] for more details. - - - -## pubspec.lock files +## Internal information -`pubspec.lock` files are not git ignored to make the bots faster. +For Google-internal information see go/a2ui-internal. -If you include `pubspec.lock` file to your PR, make sure to run `flutter pub upgrade`, -when your Flutter is latest at beta channel. -## Internal information -For Google-internal information see go/a2ui-internal. diff --git a/docs/contributing/README.md b/docs/contributing/README.md index 3e37dc3aa..7a39e8fc7 100644 --- a/docs/contributing/README.md +++ b/docs/contributing/README.md @@ -1,4 +1,4 @@ -# GenUI specifications +# Contributing to this repository This folder provides guidance for contributors, targeted at both AI models and human developers. @@ -11,6 +11,7 @@ This directory contains the following specifications: - [Design](design.md) - [Pull requests](pull_requests.md) - [Publishing](publishing.md) +- [Examples](../../examples/README.md) ## Note for AI models @@ -32,3 +33,36 @@ I have read and understood ./docs/contributing/README.md. To run a script in `tool/`, open the script in VSCode and press ⇧⌘B. +## Versioning + +We use [Semver] for package versioning, although before 1.0.0, we will be +incrementing only the minor number for breaking changes and the patch number for +non-breaking changes. After 1.0.0, we will be using standard Semver, bumping the +major number for breaking changes. + +We release the following packages in lock step, +with the same version number, so when one is released, they are all released: + +* `genui` +* `genui_a2a` +* `genui_firebase_ai` +* `genui_google_generative_ui` + +These packages are released independently on their own schedule, with their +own version number: + +* `genai_primitives` +* `json_schema_builder` + +## pubspec.lock files + +`pubspec.lock` files are not git ignored to make the bots faster. + +If you include `pubspec.lock` file to your PR, make sure to run `flutter pub upgrade`, +when your Flutter is latest at beta channel. + + + + + +[Semver]: https://semver.org/ diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index e69de29bb..8dcd8bc1d 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -0,0 +1,5 @@ + +## Publishing + +Publishing is happening automatically via GitHub actions. +See [Publishing automation][publishing-automation] for more details. \ No newline at end of file From 9425693c5f726c5ce9860025373400e3b376556f Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 12:13:07 -0700 Subject: [PATCH 06/32] Update CONTRIBUTING.md --- CONTRIBUTING.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38a449727..2f6e4b0c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,11 +76,8 @@ For Google-internal information see go/a2ui-internal. -[pub.dev]: https://pub.dev -[Semver]: https://semver.org/ [for-front-line]: https://github.com/flutter/genui/issues?q=is%3Aissue%20state%3Aopen%20-label%3AP0%20%20-label%3AP1%20-label%3AP2%20%20-label%3AP3%20-label%3Afront-line-handled [flutter_guidelines]: https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md -[readme_md]: packages/genui/README.md#configure-firebase-ai-logic [assigned_p2_p3_issues]: https://github.com/flutter/genui/issues?q=is%3Aopen%20is%3Aissue%20label%3AP2%2CP3%20assignee%3A* [p0_p1_issues_without_milestone]: https://github.com/flutter/genui/issues?q=is%3Aopen%20is%3Aissue%20label%3AP1%2CP0%20no%3Amilestone [projectless_open_issues]: https://github.com/flutter/genui/issues?q=is%3Aopen%20is%3Aissue%20no%3Aproject From 6554fc1802ec0350335f57efc6e12f079a32404d Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 12:13:47 -0700 Subject: [PATCH 07/32] - --- CONTRIBUTING.md | 2 -- docs/contributing/README.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2f6e4b0c0..24d040932 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,8 +72,6 @@ empty as possible. For Google-internal information see go/a2ui-internal. - - [for-front-line]: https://github.com/flutter/genui/issues?q=is%3Aissue%20state%3Aopen%20-label%3AP0%20%20-label%3AP1%20-label%3AP2%20%20-label%3AP3%20-label%3Afront-line-handled diff --git a/docs/contributing/README.md b/docs/contributing/README.md index 7a39e8fc7..5e7ce5018 100644 --- a/docs/contributing/README.md +++ b/docs/contributing/README.md @@ -61,8 +61,6 @@ own version number: If you include `pubspec.lock` file to your PR, make sure to run `flutter pub upgrade`, when your Flutter is latest at beta channel. - - [Semver]: https://semver.org/ From 1afbe08d7d2714d25258999820ca63280f75ac4f Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 15 May 2026 12:23:59 -0700 Subject: [PATCH 08/32] Update pull_requests.md --- docs/contributing/pull_requests.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/contributing/pull_requests.md b/docs/contributing/pull_requests.md index a6fa81153..66163c13e 100644 --- a/docs/contributing/pull_requests.md +++ b/docs/contributing/pull_requests.md @@ -1,2 +1,8 @@ # Authoring pull requests +When authoring a PR, you may get errors related to release-automation. + +Follow [this guidance][release_automation_guidance] to resolve them. + +[release_automation_guidance]: + From 0f7cfa5fe9d15013e42cb12cd4c9bb9e8689a82d Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 13:20:57 -0700 Subject: [PATCH 09/32] - --- docs/contributing/README.md | 19 ------------ docs/contributing/publishing.md | 48 ++++++++++++++++++++++++++++-- docs/contributing/pull_requests.md | 15 ++++++++++ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/docs/contributing/README.md b/docs/contributing/README.md index 5e7ce5018..a589e8e3f 100644 --- a/docs/contributing/README.md +++ b/docs/contributing/README.md @@ -33,26 +33,7 @@ I have read and understood ./docs/contributing/README.md. To run a script in `tool/`, open the script in VSCode and press ⇧⌘B. -## Versioning -We use [Semver] for package versioning, although before 1.0.0, we will be -incrementing only the minor number for breaking changes and the patch number for -non-breaking changes. After 1.0.0, we will be using standard Semver, bumping the -major number for breaking changes. - -We release the following packages in lock step, -with the same version number, so when one is released, they are all released: - -* `genui` -* `genui_a2a` -* `genui_firebase_ai` -* `genui_google_generative_ui` - -These packages are released independently on their own schedule, with their -own version number: - -* `genai_primitives` -* `json_schema_builder` ## pubspec.lock files diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 8dcd8bc1d..6014faf1b 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -1,5 +1,47 @@ -## Publishing +# Publishing -Publishing is happening automatically via GitHub actions. -See [Publishing automation][publishing-automation] for more details. \ No newline at end of file +Publishing is happening automatically via GitHub actions, with help of +[firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). + +There are two CI workflows that enable this automation: + +1. [post_summaries.yaml](../../.github/workflows/post_summaries.yaml) +2. [publish.yaml](../../.github/workflows/publish.yaml) + +## Making PR passing `publish / validate` + +In general, the job [publish / validate](https://github.com/flutter/genui/actions/runs/25936562918) checks if all [pub.dev](https://pub.dev) packages are release ready. + +To make sure your PR passes this validation, follow [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). + +## `-dev` vs non-`-dev` (production ready) versions + +The packages code should be always release ready. That means: + +1. Use `-dev` version if your changes don't touch any published code or docs. For example, you changed tests, tools, or not-publisshed docs. + +2. If your feature is partially implemented, hide the feature's code behind a false by default, and use non-dev version. + +## Versioning + +We use [Semver] for package versioning, although before 1.0.0, we will be +incrementing only the minor number for breaking changes and the patch number for +non-breaking changes. After 1.0.0, we will be using standard Semver, bumping the +major number for breaking changes. + +We release the following packages in lock step, +with the same version number, so when one is released, they are all released: + +* `genui` +* `genui_a2a` +* `genui_firebase_ai` +* `genui_google_generative_ui` + +These packages are released independently on their own schedule, with their +own version number: + +* `genai_primitives` +* `json_schema_builder` + +[Semver]: https://semver.org/ diff --git a/docs/contributing/pull_requests.md b/docs/contributing/pull_requests.md index a6fa81153..18854027e 100644 --- a/docs/contributing/pull_requests.md +++ b/docs/contributing/pull_requests.md @@ -1,2 +1,17 @@ # Authoring pull requests +## Make your PR easy to review + +1. Make sure your PR has meaningful title and description. +2. Make sure your PR is not too large. Smaller PRs are easier to review. +3. Separate code reorgs from feature changes. + +## CI presubmit errors + +You may get CI presubmit errors on pull requests for several reasons. This sections explains how to fix some of not obvious ones. + +### From `publish / validate` job + +In general, the job checks if all [pub.dev](https://pub.dev) packages are release ready. + +See [publishing.md](publishing.md) for more details. From bca0e66839dd6085d7f6c143ec7b1504604faa1c Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 13:42:48 -0700 Subject: [PATCH 10/32] Update publishing.md --- docs/contributing/publishing.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 6014faf1b..0ab1e7c4f 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -1,7 +1,7 @@ -# Publishing +# Publishing -Publishing is happening automatically via GitHub actions, with help of +Publishing to [pub.dev](https://pub.dev) is happening automatically via GitHub actions, with help of [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). There are two CI workflows that enable this automation: @@ -11,7 +11,7 @@ There are two CI workflows that enable this automation: ## Making PR passing `publish / validate` -In general, the job [publish / validate](https://github.com/flutter/genui/actions/runs/25936562918) checks if all [pub.dev](https://pub.dev) packages are release ready. +In general, the job [publish / validate](https://github.com/flutter/genui/actions/runs/25936562918) checks if all pub.dev packages are ready for publishing. To make sure your PR passes this validation, follow [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). @@ -23,6 +23,14 @@ The packages code should be always release ready. That means: 2. If your feature is partially implemented, hide the feature's code behind a false by default, and use non-dev version. +## Package categories + +`pub.dev` packages in this repo fall into three categories: + +1. **Not published**: they have `release: none` in their `pubspec.yaml`. +2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, with the same version number. +3. **Independent packages**: they don't have `resolution` in their `pubspec.yaml`. They are released independently. + ## Versioning We use [Semver] for package versioning, although before 1.0.0, we will be @@ -30,18 +38,6 @@ incrementing only the minor number for breaking changes and the patch number for non-breaking changes. After 1.0.0, we will be using standard Semver, bumping the major number for breaking changes. -We release the following packages in lock step, -with the same version number, so when one is released, they are all released: - -* `genui` -* `genui_a2a` -* `genui_firebase_ai` -* `genui_google_generative_ui` - -These packages are released independently on their own schedule, with their -own version number: - -* `genai_primitives` -* `json_schema_builder` + [Semver]: https://semver.org/ From 0a6181a11c4a372ff8e6a059f797a0c4f0d54712 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 13:44:34 -0700 Subject: [PATCH 11/32] Update publishing.md --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 0ab1e7c4f..e7befd65c 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -29,7 +29,7 @@ The packages code should be always release ready. That means: 1. **Not published**: they have `release: none` in their `pubspec.yaml`. 2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, with the same version number. -3. **Independent packages**: they don't have `resolution` in their `pubspec.yaml`. They are released independently. +3. **Independent packages**: they don't have `release: none` and `resolution` in their `pubspec.yaml`. They are released independently. ## Versioning From 40c9e68b7ba30a122f83d85db5b4f1282831180c Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:09:56 -0700 Subject: [PATCH 12/32] - --- docs/contributing/publishing.md | 21 +++++++++++++-------- packages/a2ui_core/CHANGELOG.md | 2 +- packages/genai_primitives/pubspec.yaml | 2 +- packages/genui/CHANGELOG.md | 4 ---- packages/json_schema_builder/pubspec.yaml | 2 +- tool/fix_copyright/pubspec.yaml | 1 + 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index e7befd65c..afb6631fb 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -15,21 +15,26 @@ In general, the job [publish / validate](https://github.com/flutter/genui/action To make sure your PR passes this validation, follow [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). +## Package categories + +`pub.dev` packages in this repo fall into three categories: + +1. **Not intended to be published**: they have `publish_to: none` in their `pubspec.yaml`. +2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, in lock-step, with the same version number. +3. **Independent packages**: they don't have `publish_to` and `resolution` fields in their `pubspec.yaml`. They are released independently. +4. **Not yet published packages**: they have `resolution: workspace` and `release: none` in their `pubspec.yaml`. + ## `-dev` vs non-`-dev` (production ready) versions The packages code should be always release ready. That means: -1. Use `-dev` version if your changes don't touch any published code or docs. For example, you changed tests, tools, or not-publisshed docs. - -2. If your feature is partially implemented, hide the feature's code behind a false by default, and use non-dev version. +1. Use `-dev` version if **at least one** of the following statements is true: -## Package categories + 1.1. The package is planned to be released in future. In this case it is published with `-dev` suffix in order to reserve the package name. -`pub.dev` packages in this repo fall into three categories: + 1.2. The package's changes touches only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in-lock with other package that has publishable code. -1. **Not published**: they have `release: none` in their `pubspec.yaml`. -2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, with the same version number. -3. **Independent packages**: they don't have `release: none` and `resolution` in their `pubspec.yaml`. They are released independently. +2. If your feature is partially implemented, hide the feature's code behind a false by default, and use **release-ready** version. ## Versioning diff --git a/packages/a2ui_core/CHANGELOG.md b/packages/a2ui_core/CHANGELOG.md index 35062b993..02e519a76 100644 --- a/packages/a2ui_core/CHANGELOG.md +++ b/packages/a2ui_core/CHANGELOG.md @@ -1,5 +1,5 @@ # `a2ui_core` Changelog -## 0.0.1 (in progress) +## 0.0.1-dev002 - Initial version. \ No newline at end of file diff --git a/packages/genai_primitives/pubspec.yaml b/packages/genai_primitives/pubspec.yaml index cfd0ee9c7..176937a19 100644 --- a/packages/genai_primitives/pubspec.yaml +++ b/packages/genai_primitives/pubspec.yaml @@ -4,7 +4,7 @@ name: genai_primitives description: A set of primitives for working with generative AI. -version: 0.2.3 +version: 0.2.4 homepage: https://github.com/flutter/genui/tree/main/packages/genai_primitives license: BSD-3-Clause issue_tracker: https://github.com/flutter/genui/issues diff --git a/packages/genui/CHANGELOG.md b/packages/genui/CHANGELOG.md index e7f995bc7..721788460 100644 --- a/packages/genui/CHANGELOG.md +++ b/packages/genui/CHANGELOG.md @@ -1,9 +1,5 @@ # `genui` Changelog -## (WIP) - -- **Feature**: Updated example/README.md. - ## 0.9.0 - **BREAKING**: Reorganized library exports (#866). diff --git a/packages/json_schema_builder/pubspec.yaml b/packages/json_schema_builder/pubspec.yaml index a633b0320..0c359cbc4 100644 --- a/packages/json_schema_builder/pubspec.yaml +++ b/packages/json_schema_builder/pubspec.yaml @@ -4,7 +4,7 @@ name: json_schema_builder description: A full-featured package used to build and validate JSON schemas in Dart. -version: 0.1.3 +version: 0.1.4 homepage: https://github.com/flutter/genui/tree/main/packages/json_schema_builder license: BSD-3-Clause issue_tracker: https://github.com/flutter/genui/issues diff --git a/tool/fix_copyright/pubspec.yaml b/tool/fix_copyright/pubspec.yaml index 61c7a88be..551014096 100644 --- a/tool/fix_copyright/pubspec.yaml +++ b/tool/fix_copyright/pubspec.yaml @@ -4,6 +4,7 @@ name: fix_copyright description: A command line app to fix copyright headers. +publish_to: none version: 0.1.0 environment: From 2f072a497aa54195d567340635dbc89a49137681 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:13:03 -0700 Subject: [PATCH 13/32] Update publishing.md --- docs/contributing/publishing.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index afb6631fb..471b777aa 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -46,3 +46,7 @@ major number for breaking changes. [Semver]: https://semver.org/ + +## How publishing happens? + +TODO(polina-c): add information, https://github.com/google/A2UI/issues/1383 From 56d618f9c7db6ab2ed4f1a86716e1ef527e58c28 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:13:30 -0700 Subject: [PATCH 14/32] - --- .github/workflows/post_summaries.yaml | 4 ++++ .github/workflows/publish.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/post_summaries.yaml b/.github/workflows/post_summaries.yaml index cb937381c..8e9171ae7 100644 --- a/.github/workflows/post_summaries.yaml +++ b/.github/workflows/post_summaries.yaml @@ -1,3 +1,7 @@ +# Copyright 2025 The Flutter Authors. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + # A CI configuration for pub-publish to write comments on PRs. name: Comment on the pull request diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 95de03c81..c29f437d2 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,3 +1,7 @@ +# Copyright 2025 The Flutter Authors. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + # A CI configuration to auto-publish pub packages. name: Publish From 99390640e3bfb8ee5eaa38d9e54e3159090b0e0e Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:26:09 -0700 Subject: [PATCH 15/32] - --- packages/genai_primitives/CHANGELOG.md | 4 ---- packages/genai_primitives/pubspec.yaml | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/genai_primitives/CHANGELOG.md b/packages/genai_primitives/CHANGELOG.md index f7cea1865..2462a5388 100644 --- a/packages/genai_primitives/CHANGELOG.md +++ b/packages/genai_primitives/CHANGELOG.md @@ -1,9 +1,5 @@ # `genai_primitives` Changelog -## 0.2.4 (in progress) - -- **Refactor**: Update core framework to v0.9 (#546dab9be). - ## 0.2.3 - **Feature**: Add methods `copyWith` and `concatenate` to `ChatMessage` (#760). diff --git a/packages/genai_primitives/pubspec.yaml b/packages/genai_primitives/pubspec.yaml index 176937a19..cfd0ee9c7 100644 --- a/packages/genai_primitives/pubspec.yaml +++ b/packages/genai_primitives/pubspec.yaml @@ -4,7 +4,7 @@ name: genai_primitives description: A set of primitives for working with generative AI. -version: 0.2.4 +version: 0.2.3 homepage: https://github.com/flutter/genui/tree/main/packages/genai_primitives license: BSD-3-Clause issue_tracker: https://github.com/flutter/genui/issues From 751f97084780d4a8b4a4ee6160d7cd270b1b7e81 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:30:46 -0700 Subject: [PATCH 16/32] - --- docs/contributing/publishing.md | 2 ++ packages/genui/CHANGELOG.md | 4 ++++ packages/genui/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 471b777aa..0bda64bf3 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -34,6 +34,8 @@ The packages code should be always release ready. That means: 1.2. The package's changes touches only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in-lock with other package that has publishable code. + You can publish `-dev` versions, if you need it for development. + 2. If your feature is partially implemented, hide the feature's code behind a false by default, and use **release-ready** version. ## Versioning diff --git a/packages/genui/CHANGELOG.md b/packages/genui/CHANGELOG.md index 721788460..1111a7413 100644 --- a/packages/genui/CHANGELOG.md +++ b/packages/genui/CHANGELOG.md @@ -1,5 +1,9 @@ # `genui` Changelog +## 0.9.1 + +- **Feature**: Updated example/README.md. + ## 0.9.0 - **BREAKING**: Reorganized library exports (#866). diff --git a/packages/genui/pubspec.yaml b/packages/genui/pubspec.yaml index a4db1ea46..8203836c0 100644 --- a/packages/genui/pubspec.yaml +++ b/packages/genui/pubspec.yaml @@ -4,7 +4,7 @@ name: genui description: Generates and displays generative user interfaces (GenUI) in Flutter using AI. -version: 0.9.0 +version: 0.9.1 homepage: https://github.com/flutter/genui/tree/main/packages/genui license: BSD-3-Clause issue_tracker: https://github.com/flutter/genui/issues From 33359adce0c0b111a60eb2a8d3dd3de69c500aba Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:33:28 -0700 Subject: [PATCH 17/32] Update docs/contributing/pull_requests.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/pull_requests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/pull_requests.md b/docs/contributing/pull_requests.md index 18854027e..f39833ce3 100644 --- a/docs/contributing/pull_requests.md +++ b/docs/contributing/pull_requests.md @@ -8,7 +8,7 @@ ## CI presubmit errors -You may get CI presubmit errors on pull requests for several reasons. This sections explains how to fix some of not obvious ones. +You may get CI presubmit errors on pull requests for several reasons. This section explains how to fix some of the less obvious ones. ### From `publish / validate` job From c5cb8b1faa9a21f34fefeb66be63895ed09768db Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:37:42 -0700 Subject: [PATCH 18/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 0bda64bf3..723e61ee9 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -36,7 +36,7 @@ The packages code should be always release ready. That means: You can publish `-dev` versions, if you need it for development. -2. If your feature is partially implemented, hide the feature's code behind a false by default, and use **release-ready** version. +2. If your feature is partially implemented, hide the feature's code behind a false-by-default flag, and use **release-ready** version. ## Versioning From 667bad4a6964ac64111b3478294167052217e02f Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:38:07 -0700 Subject: [PATCH 19/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 723e61ee9..b9035d12f 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -32,7 +32,7 @@ The packages code should be always release ready. That means: 1.1. The package is planned to be released in future. In this case it is published with `-dev` suffix in order to reserve the package name. - 1.2. The package's changes touches only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in-lock with other package that has publishable code. + 1.2. The package's changes touch only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in lock-step with another package that has publishable code. You can publish `-dev` versions, if you need it for development. From 7d81961ca2e25456601bd2b2cd33f6986f9a934b Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:38:20 -0700 Subject: [PATCH 20/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index b9035d12f..5f1334f23 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -1,7 +1,7 @@ # Publishing -Publishing to [pub.dev](https://pub.dev) is happening automatically via GitHub actions, with help of +Publishing to [pub.dev](https://pub.dev) happens automatically via GitHub Actions, with the help of [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose). There are two CI workflows that enable this automation: From 61c45a30bd0178e54e4a40cd61d2dd5690732d70 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:38:32 -0700 Subject: [PATCH 21/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 5f1334f23..26715cd86 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -9,7 +9,7 @@ There are two CI workflows that enable this automation: 1. [post_summaries.yaml](../../.github/workflows/post_summaries.yaml) 2. [publish.yaml](../../.github/workflows/publish.yaml) -## Making PR passing `publish / validate` +## Passing the publish / validate job In general, the job [publish / validate](https://github.com/flutter/genui/actions/runs/25936562918) checks if all pub.dev packages are ready for publishing. From 656824b10af9570991de675bdda7967c88a55180 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:39:48 -0700 Subject: [PATCH 22/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 26715cd86..6bbb17cd5 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -30,7 +30,7 @@ The packages code should be always release ready. That means: 1. Use `-dev` version if **at least one** of the following statements is true: - 1.1. The package is planned to be released in future. In this case it is published with `-dev` suffix in order to reserve the package name. + 1.1. The package is planned to be released in the future. In this case it is published with `-dev` suffix in order to reserve the package name. 1.2. The package's changes touch only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in lock-step with another package that has publishable code. From 36a982f74530ebd7ec15a8a1b011fede3f9ab2ce Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:40:31 -0700 Subject: [PATCH 23/32] - --- packages/genui/.pubignore | 1 + packages/genui/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 packages/genui/.pubignore diff --git a/packages/genui/.pubignore b/packages/genui/.pubignore new file mode 100644 index 000000000..539b4cdd5 --- /dev/null +++ b/packages/genui/.pubignore @@ -0,0 +1 @@ +submodules/ diff --git a/packages/genui/pubspec.yaml b/packages/genui/pubspec.yaml index 8203836c0..7ff74989c 100644 --- a/packages/genui/pubspec.yaml +++ b/packages/genui/pubspec.yaml @@ -11,7 +11,7 @@ issue_tracker: https://github.com/flutter/genui/issues environment: sdk: ">=3.10.0 <4.0.0" - flutter: ">=3.35.7 <4.0.0" + flutter: ">=3.35.7" resolution: workspace From 2311ab7435bcf5e1c94abf0e35e8a08ebcb1f65e Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:42:28 -0700 Subject: [PATCH 24/32] Update publishing.md --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 6bbb17cd5..3e0b6f683 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -17,7 +17,7 @@ To make sure your PR passes this validation, follow [firehose rules](https://git ## Package categories -`pub.dev` packages in this repo fall into three categories: +`pub.dev` packages in this repo fall into the following categories: 1. **Not intended to be published**: they have `publish_to: none` in their `pubspec.yaml`. 2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, in lock-step, with the same version number. From 2c2158a09b955debc12dc4de0e94c51f025eb331 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:54:23 -0700 Subject: [PATCH 25/32] Update publishing.md --- docs/contributing/publishing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 3e0b6f683..11ced7b7e 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -6,8 +6,8 @@ Publishing to [pub.dev](https://pub.dev) happens automatically via GitHub Action There are two CI workflows that enable this automation: -1. [post_summaries.yaml](../../.github/workflows/post_summaries.yaml) -2. [publish.yaml](../../.github/workflows/publish.yaml) +1. [post_summaries.yaml](../../.github/workflows/post_summaries.yaml) - job `publish / validate` runs on pre-submit. +2. [publish.yaml](../../.github/workflows/publish.yaml) - job `publish / publish` runs on tagging. ## Passing the publish / validate job From f6dbe2b3311698ba1aac5b0047c35d3743f24634 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 14:56:22 -0700 Subject: [PATCH 26/32] Skip submodule checkout in publish workflow Avoids pub publish --dry-run flagging gitignored-but-checked-in files inside the a2ui submodule. The genui package's published sources don't depend on submodule contents. --- .github/workflows/publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index c29f437d2..81f6ff8cd 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -23,7 +23,7 @@ jobs: sdk: beta # version of dart sdk to use for publishing use-flutter: true write-comments: false - checkout_submodules: true + checkout_submodules: false permissions: id-token: write pull-requests: write From 5a7244c6d6ac1a520b302e91bdfcfe8bcffb1a7b Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:07:10 -0700 Subject: [PATCH 27/32] Remove .pubignore files With checkout_submodules: false in the publish workflow, the submodule contents aren't present at validation time, so the .pubignore rules aren't needed and were themselves matching the bare gitlinks, triggering 'tracked but ignored' warnings. --- packages/genui/.pubignore | 1 - packages/json_schema_builder/.pubignore | 1 - 2 files changed, 2 deletions(-) delete mode 100644 packages/genui/.pubignore delete mode 100644 packages/json_schema_builder/.pubignore diff --git a/packages/genui/.pubignore b/packages/genui/.pubignore deleted file mode 100644 index 539b4cdd5..000000000 --- a/packages/genui/.pubignore +++ /dev/null @@ -1 +0,0 @@ -submodules/ diff --git a/packages/json_schema_builder/.pubignore b/packages/json_schema_builder/.pubignore deleted file mode 100644 index 28b2338cf..000000000 --- a/packages/json_schema_builder/.pubignore +++ /dev/null @@ -1 +0,0 @@ -submodules/JSON-Schema-Test-Suite/** From 1bcefe5b6ca2019bb5e445df01df34b57b883aff Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:22:47 -0700 Subject: [PATCH 28/32] Move submodules to repo root Relocates the a2ui and JSON-Schema-Test-Suite git submodules from inside packages/ to a top-level submodules/ directory so they are not part of any pub package's source tree. This unblocks pub publish --dry-run for genui and json_schema_builder, which was flagging the submodule gitlinks as 'tracked but ignored'. - packages/genui/submodules/a2ui -> submodules/a2ui - packages/json_schema_builder/submodules/JSON-Schema-Test-Suite -> submodules/JSON-Schema-Test-Suite Updates: - .gitmodules paths - analysis_options.yaml exclude pattern - json_schema_builder test fixture paths (now ../../submodules/...) - .agent/skills/genui-helper/SKILL.md references --- .agent/skills/genui-helper/SKILL.md | 6 +++--- .gitmodules | 6 +++--- analysis_options.yaml | 2 +- packages/json_schema_builder/test/test_suite_test.dart | 6 ++++-- .../submodules => submodules}/JSON-Schema-Test-Suite | 0 {packages/genui/submodules => submodules}/a2ui | 0 6 files changed, 11 insertions(+), 9 deletions(-) rename {packages/json_schema_builder/submodules => submodules}/JSON-Schema-Test-Suite (100%) rename {packages/genui/submodules => submodules}/a2ui (100%) diff --git a/.agent/skills/genui-helper/SKILL.md b/.agent/skills/genui-helper/SKILL.md index d74154b53..e1e10efd9 100644 --- a/.agent/skills/genui-helper/SKILL.md +++ b/.agent/skills/genui-helper/SKILL.md @@ -51,9 +51,9 @@ When creating a new UI component in `genui`: ## References - A2UI Specification - - Available in the submodule at @packages/genui/submodules/a2ui - - The specification documentation is available in @packages/genui/submodules/a2ui/specification/v0.9/docs - - The specification schemas are available in @packages/genui/submodules/a2ui/specification/v0.9/json + - Available in the submodule at @submodules/a2ui + - The specification documentation is available in @submodules/a2ui/specification/v0.9/docs + - The specification schemas are available in @submodules/a2ui/specification/v0.9/json - Because it is a submodule, you may need to update the submodule to get the latest specification. - To find out details of a specific dart compiler diagnostic message, use the following url format to look up the details: - https://dart.dev/tools/diagnostics/ diff --git a/.gitmodules b/.gitmodules index 8d7b0c972..60a71f889 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ -[submodule "packages/json_schema_builder/submodules/JSON-Schema-Test-Suite"] - path = packages/json_schema_builder/submodules/JSON-Schema-Test-Suite +[submodule "JSON-Schema-Test-Suite"] + path = submodules/JSON-Schema-Test-Suite url = https://github.com/json-schema-org/JSON-Schema-Test-Suite.git [submodule "a2ui"] - path = packages/genui/submodules/a2ui + path = submodules/a2ui url = https://github.com/google/A2UI.git branch = main diff --git a/analysis_options.yaml b/analysis_options.yaml index 60b7cd58f..c5c631aed 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -6,7 +6,7 @@ include: package:lints/recommended.yaml analyzer: exclude: - - 'packages/genui/submodules/**' + - 'submodules/**' language: strict-casts: true strict-inference: true diff --git a/packages/json_schema_builder/test/test_suite_test.dart b/packages/json_schema_builder/test/test_suite_test.dart index e3668ec2f..a534737fa 100644 --- a/packages/json_schema_builder/test/test_suite_test.dart +++ b/packages/json_schema_builder/test/test_suite_test.dart @@ -12,9 +12,11 @@ import 'package:test/test.dart'; void main() { final testSuiteDir = Directory( - 'submodules/JSON-Schema-Test-Suite/tests/draft2020-12', + '../../submodules/JSON-Schema-Test-Suite/tests/draft2020-12', + ); + final remoteDir = Directory( + '../../submodules/JSON-Schema-Test-Suite/remotes', ); - final remoteDir = Directory('submodules/JSON-Schema-Test-Suite/remotes'); // Optional tests are not required to pass for full compliance. final optionalTestSuiteDir = Directory('${testSuiteDir.path}/optional'); diff --git a/packages/json_schema_builder/submodules/JSON-Schema-Test-Suite b/submodules/JSON-Schema-Test-Suite similarity index 100% rename from packages/json_schema_builder/submodules/JSON-Schema-Test-Suite rename to submodules/JSON-Schema-Test-Suite diff --git a/packages/genui/submodules/a2ui b/submodules/a2ui similarity index 100% rename from packages/genui/submodules/a2ui rename to submodules/a2ui From d0827cdbc45d8463d8faeda81acf7b1e759359a2 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:43:33 -0700 Subject: [PATCH 29/32] - --- docs/contributing/publishing.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 11ced7b7e..30a4830b4 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -17,12 +17,13 @@ To make sure your PR passes this validation, follow [firehose rules](https://git ## Package categories -`pub.dev` packages in this repo fall into the following categories: +Packages in this repo fall into the following categories: -1. **Not intended to be published**: they have `publish_to: none` in their `pubspec.yaml`. -2. **Mono-repo packages**: they have `resolution: workspace` in their `pubspec.yaml`, and are released together, in lock-step, with the same version number. -3. **Independent packages**: they don't have `publish_to` and `resolution` fields in their `pubspec.yaml`. They are released independently. -4. **Not yet published packages**: they have `resolution: workspace` and `release: none` in their `pubspec.yaml`. +1. **Not published**: `pubspec.yaml` contains `publish_to: none`. Workspace tools and example apps that are never pushed to pub.dev. +2. **Not yet published**: the package's `version:` ends with a `-dev` suffix (see "`-dev` vs non-`-dev`" below). Published to pub.dev only to reserve the name; not ready for general use yet. +3. **Published**: any other package. Each has its own version cadence on pub.dev. + +Note: `resolution: workspace` in a `pubspec.yaml` is a tooling concern — it tells Dart to share dependency resolution and a lockfile with the monorepo, and it does **not** by itself imply anything about release cadence. A package can opt out of the workspace (omit `resolution: workspace`) to avoid circular dependencies or unrelated update churn while still being a published package. ## `-dev` vs non-`-dev` (production ready) versions @@ -32,7 +33,7 @@ The packages code should be always release ready. That means: 1.1. The package is planned to be released in the future. In this case it is published with `-dev` suffix in order to reserve the package name. - 1.2. The package's changes touch only pub.dev non-publishable code or docs (like tests, tools, or not-publishable docs) and it is not a mono-repo package in lock-step with another package that has publishable code. + 1.2. The package's changes touch only non-publishable code or docs (like tests, tools, or not-publishable docs). You can publish `-dev` versions, if you need it for development. From 5e121db645b151625f396ebfe3411a0d267b80e1 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:50:09 -0700 Subject: [PATCH 30/32] - --- tool/release/README.md | 77 ---------- tool/release/bin/release.dart | 141 ----------------- tool/release/lib/release.dart | 53 ------- tool/release/lib/src/bump.dart | 124 --------------- tool/release/lib/src/exceptions.dart | 12 -- tool/release/lib/src/publish.dart | 217 --------------------------- tool/release/lib/src/utils.dart | 45 ------ tool/release/pubspec.yaml | 23 --- tool/release/test/bump_test.dart | 114 -------------- tool/release/test/publish_test.dart | 196 ------------------------ tool/release/test/release_test.dart | 153 ------------------- 11 files changed, 1155 deletions(-) delete mode 100644 tool/release/README.md delete mode 100644 tool/release/bin/release.dart delete mode 100644 tool/release/lib/release.dart delete mode 100644 tool/release/lib/src/bump.dart delete mode 100644 tool/release/lib/src/exceptions.dart delete mode 100644 tool/release/lib/src/publish.dart delete mode 100644 tool/release/lib/src/utils.dart delete mode 100644 tool/release/pubspec.yaml delete mode 100644 tool/release/test/bump_test.dart delete mode 100644 tool/release/test/publish_test.dart delete mode 100644 tool/release/test/release_test.dart diff --git a/tool/release/README.md b/tool/release/README.md deleted file mode 100644 index 67a54fc82..000000000 --- a/tool/release/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Monorepo Release Tool - -This Dart-based command-line tool automates the package publishing process for this monorepo using a safe, two-stage workflow. - -## Prerequisites - -#### Permissions to publish a package to pub.dev - -Make sure you have 'admin' permissions for the [labs.flutter.dev publisher](https://pub.dev/publishers/labs.flutter.dev), which you can verify on the [admin page](https://pub.dev/publishers/labs.flutter.dev/admin). - -If you do not have permissions, ask an existing admin from the linked page to add you. - -## How to release GenUI SDK - -The process is a two-stage publish workflow. It is split into two distinct commands, `bump` and `publish`, -to separate release preparation from the act of publishing. - -### 0. Update Dependencies - -Before running `bump`, make sure you are using the latest Flutter stable release, and update dependencies to the latest stable versions. This can be done by running: - -```bash -dart pub upgrade --major-versions -``` - -Also, use Antigravity or Gemini CLI to update `CHANGELOG.md` files. You can use a prompt like: - -```txt -Look at the git diffs since the tag and add any missing changelog entries for breaking and other changes to each of the packages which have CHANGELOG.md files. -``` - -Where `` is the tag of the previous release. For example, if the previous release was `genui-0.6.1`, then the command would be: - -```txt -Look at the git diffs since the genui-0.6.1 tag and add any missing changelog entries for breaking and other changes to each of the packages which have CHANGELOG.md files. -``` - -### 1. Prepare for Publish with `bump` - -First, run the `bump` command to prepare the repository for a new release. This will bump the version numbers, finalize the changelogs, and upgrade dependencies. After running this command, you should review the changes, make any necessary manual adjustments, and then commit the changes to your version control system. - -**Syntax:** - -```bash -dart run tool/release/bin/release.dart bump --level -``` - -**`` can be one of:** - -- `breaking`: Increments the major version for breaking changes. -- `major`: Increments the major version. -- `minor`: Increments the minor version for new features. -- `patch`: Increments the patch version for bug fixes. - -### 2. Publish and Prepare for Next Publish Cycle with `publish` - -After you have committed the changes from the `bump` command, you can publish the new version. The `publish` command will publish the packages, create git tags, and then prepare the repository for the next development cycle by adding a new `(in progress)` section to top of the CHANGELOG.md files. - -By default, `publish` runs in dry-run mode, which simulates the publish process without actually uploading packages. - -**Command:** - -```bash -dart run tool/release/bin/release.dart publish -``` - -#### Actual Publish - -To perform a real publish, use the `--force` flag. The tool will first perform a dry run. If successful, it will prompt for confirmation before proceeding. - -**Command:** - -```bash -dart run tool/release/bin/release.dart publish --force -``` - -After a successful publish, the tool will create local git tags for each published package and print the command needed to push them to the remote repository. You should then push the tags, and commit the new changes to the `CHANGELOG.md` files to start the next development cycle. diff --git a/tool/release/bin/release.dart b/tool/release/bin/release.dart deleted file mode 100644 index 7dd8e0a16..000000000 --- a/tool/release/bin/release.dart +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io' as io; -import 'dart:io' show IOSink, Platform, exit; - -import 'package:args/args.dart'; -import 'package:file/file.dart'; -import 'package:file/local.dart'; -import 'package:process_runner/process_runner.dart'; -import 'package:release/release.dart'; -import 'package:release/src/exceptions.dart'; - -Future main(List arguments) async { - exit(await run(arguments)); -} - -Future run( - List arguments, { - IOSink? stdout, - IOSink? stderr, -}) async { - final IOSink actualStdout = stdout ?? io.stdout; - final IOSink actualStderr = stderr ?? io.stderr; - final parser = ArgParser() - ..addFlag( - 'help', - abbr: 'h', - negatable: false, - help: 'Print this usage information.', - ); - - final bumpParser = ArgParser() - ..addOption( - 'level', - abbr: 'l', - allowed: ['breaking', 'major', 'minor', 'patch'], - help: 'The level to bump the version by.', - mandatory: true, - ); - parser.addCommand('bump', bumpParser); - - final publishParser = ArgParser() - ..addFlag( - 'force', - abbr: 'f', - negatable: false, - help: 'Actually publish packages and create tags.', - ); - parser.addCommand('publish', publishParser); - parser.addCommand('help'); - - void printUsage({IOSink? sink}) { - final IOSink actualSink = sink ?? actualStdout; - actualSink.writeln( - 'Usage: dart run tool/release/bin/release.dart [options]', - ); - actualSink.writeln(parser.usage); - } - - final ArgResults argResults; - try { - argResults = parser.parse(arguments); - } on FormatException catch (e) { - actualStderr.writeln(e.message); - printUsage(sink: actualStderr); - return 1; - } - - if (argResults['help'] as bool) { - printUsage(); - return 0; - } - - if (argResults.command == null) { - printUsage(sink: actualStderr); - return 1; - } - - final fileSystem = const LocalFileSystem(); - final processRunner = ProcessRunner(); - - // Find the repo root, assuming the script is in /tool/release/bin - final File scriptFile = fileSystem.file(Platform.script.toFilePath()); - Directory repoDir = scriptFile.parent.parent.parent.parent; - - if (!repoDir.childFile('pubspec.yaml').existsSync()) { - // Fallback or check if we are in the wrong place? - // Try to find the root by looking up. - Directory current = scriptFile.parent; - while (current.path != current.parent.path) { - if (current.childFile('pubspec.yaml').existsSync() && - current.childDirectory('packages').existsSync()) { - repoDir = current; - break; - } - current = current.parent; - } - } - - final tool = ReleaseTool( - fileSystem: fileSystem, - processRunner: processRunner, - repoRoot: repoDir, - stdinReader: io.stdin.readLineSync, - ); - - final ArgResults command = argResults.command!; - try { - switch (command.name) { - case 'bump': - await tool.bump(command['level'] as String); - break; - case 'publish': - await tool.publish(force: command['force'] as bool); - break; - case 'help': - if (command.rest.isEmpty) { - printUsage(); - } else { - final String subcommand = command.rest.first; - final ArgParser? subParser = parser.commands[subcommand]; - if (subParser == null) { - actualStderr.writeln('Unknown command: $subcommand'); - printUsage(sink: actualStderr); - return 1; - } - actualStdout.writeln( - 'Usage: dart run tool/release/bin/release.dart $subcommand [options]', - ); - actualStdout.writeln(subParser.usage); - } - break; - } - } on ReleaseException catch (e) { - actualStderr.writeln(e); - return 1; - } - return 0; -} diff --git a/tool/release/lib/release.dart b/tool/release/lib/release.dart deleted file mode 100644 index f90ee806d..000000000 --- a/tool/release/lib/release.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io'; - -import 'package:file/file.dart'; -import 'package:process_runner/process_runner.dart'; - -import 'src/bump.dart'; -import 'src/publish.dart'; -import 'src/utils.dart'; - -export 'src/bump.dart'; -export 'src/publish.dart'; - -class ReleaseTool { - final FileSystem fileSystem; - final ProcessRunner processRunner; - final Directory repoRoot; - - late final BumpCommand _bumpCommand; - late final PublishCommand _publishCommand; - - ReleaseTool({ - required this.fileSystem, - required this.processRunner, - required this.repoRoot, - required StdinReader stdinReader, - Printer? printer, - }) { - final Printer print = - printer ?? ((String message) => stdout.writeln(message)); - _bumpCommand = BumpCommand( - fileSystem: fileSystem, - processRunner: processRunner, - repoRoot: repoRoot, - printer: print, - ); - _publishCommand = PublishCommand( - fileSystem: fileSystem, - processRunner: processRunner, - repoRoot: repoRoot, - stdinReader: stdinReader, - printer: print, - ); - } - - Future bump(String bumpLevel) => _bumpCommand.run(bumpLevel); - - Future publish({required bool force}) => - _publishCommand.run(force: force); -} diff --git a/tool/release/lib/src/bump.dart b/tool/release/lib/src/bump.dart deleted file mode 100644 index 70f867713..000000000 --- a/tool/release/lib/src/bump.dart +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file/file.dart'; -import 'package:path/path.dart' as p; -import 'package:process_runner/process_runner.dart'; - -import 'exceptions.dart'; -import 'utils.dart'; - -class BumpCommand { - final FileSystem fileSystem; - final ProcessRunner processRunner; - final Directory repoRoot; - final Printer printer; - - BumpCommand({ - required this.fileSystem, - required this.processRunner, - required this.repoRoot, - required this.printer, - }); - - Future run(String bumpLevel) async { - final List packages = await findPackages(repoRoot, printer); - - for (final packageDir in packages) { - printer('Processing package: ${p.basename(packageDir.path)}'); - await _bumpVersion(packageDir, bumpLevel); - final String newVersion = await getPackageVersion(packageDir); - await _updateChangelog(packageDir, newVersion); - } - - printer('Upgrading dependencies in the monorepo...'); - await _upgradeDependencies(); - printer('Bump command finished.'); - } - - Future _bumpVersion(Directory packageDir, String level) async { - final ProcessRunnerResult result = await processRunner.runProcess( - ['dart', 'pub', 'bump', level], - workingDirectory: packageDir, - failOk: true, - ); - if (result.exitCode != 0) { - printer('Error bumping version in ${packageDir.path}: ${result.stderr}'); - throw ReleaseException( - 'Error bumping version in ${packageDir.path}: ${result.stderr}', - ); - } - printer('Bumped $level version in ${p.basename(packageDir.path)}'); - } - - Future _updateChangelog(Directory packageDir, String newVersion) async { - final String packageName = p.basename(packageDir.path); - final File changelogFile = fileSystem.file( - p.join(packageDir.path, 'CHANGELOG.md'), - ); - final title = '# `$packageName` Changelog\n'; - - if (!await changelogFile.exists()) { - printer( - 'Warning: CHANGELOG.md not found in ${packageDir.path}, ' - 'creating one.', - ); - await changelogFile.writeAsString('$title\n## $newVersion\n\n'); - return; - } - - String content = await changelogFile.readAsString(); - List lines = content.split('\n'); - - // Ensure the title is present and correct - if (lines.isEmpty || !lines[0].startsWith('# `$packageName` Changelog')) { - // Remove any existing incorrect title - if (lines.isNotEmpty && lines[0].startsWith('# ')) { - lines.removeAt(0); - // Remove potential blank lines after the old title - while (lines.isNotEmpty && lines[0].trim().isEmpty) { - lines.removeAt(0); - } - } - content = '$title\n${lines.join('\n')}'; - lines = content.split('\n'); - } - - // Find the top-most version entry and update it. - final versionHeader = '## $newVersion'; - var versionHeaderIndex = -1; - for (var i = 0; i < lines.length; i++) { - if (lines[i].startsWith('## ')) { - versionHeaderIndex = i; - break; - } - } - - if (versionHeaderIndex != -1) { - lines[versionHeaderIndex] = versionHeader; - } else { - // If no version entry exists, add one. - var insertIndex = 1; - while (insertIndex < lines.length && lines[insertIndex].trim().isEmpty) { - insertIndex++; - } - lines.insert(insertIndex, versionHeader); - lines.insert(insertIndex + 1, ''); // Blank line after new entry - } - - await changelogFile.writeAsString(lines.join('\n')); - printer('Updated CHANGELOG.md in ${packageDir.path}'); - } - - Future _upgradeDependencies() async { - final ProcessRunnerResult result = await processRunner.runProcess( - ['dart', 'pub', 'upgrade', '--major-versions'], - workingDirectory: fileSystem.directory(repoRoot), - failOk: true, - ); - if (result.exitCode != 0) { - printer('Error running pub upgrade: ${result.stderr}'); - } - } -} diff --git a/tool/release/lib/src/exceptions.dart b/tool/release/lib/src/exceptions.dart deleted file mode 100644 index 773426f6d..000000000 --- a/tool/release/lib/src/exceptions.dart +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -class ReleaseException implements Exception { - final String message; - - ReleaseException(this.message); - - @override - String toString() => message; -} diff --git a/tool/release/lib/src/publish.dart b/tool/release/lib/src/publish.dart deleted file mode 100644 index 5483566d4..000000000 --- a/tool/release/lib/src/publish.dart +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file/file.dart'; -import 'package:path/path.dart' as p; -import 'package:process_runner/process_runner.dart'; -import 'package:pub_semver/pub_semver.dart'; - -import 'exceptions.dart'; -import 'utils.dart'; - -typedef StdinReader = String? Function(); - -class PublishCommand { - final FileSystem fileSystem; - final ProcessRunner processRunner; - final Directory repoRoot; - final StdinReader stdinReader; - final Printer printer; - - PublishCommand({ - required this.fileSystem, - required this.processRunner, - required this.repoRoot, - required this.stdinReader, - required this.printer, - }); - - Future run({required bool force}) async { - final List packages = await findPackages(repoRoot, printer); - - if (!await _performDryRun(packages)) { - throw ReleaseException('Dry run failed.'); - } - - if (!force) { - printer('Dry run successful. The following tags would be created:'); - for (final packageDir in packages) { - final String packageName = p.basename(packageDir.path); - final String version = await getPackageVersion(packageDir); - printer(' $packageName-$version'); - } - printer('Run with --force to publish.'); - return; - } - - printer('\nProceed with publishing? (yes/No)'); - final String? confirmation = stdinReader()?.toLowerCase(); - if (confirmation != 'yes' && confirmation != 'y') { - printer('Publish aborted.'); - return; - } - - final Map versionsToPublish = await _getVersionsToPublish( - packages, - ); - - await _performPublish(packages); - await _createTags(versionsToPublish); - await _prepareNextCycle(packages); - } - - Future _performDryRun(List packages) async { - printer('--- Starting Dry Run ---'); - var dryRunFailed = false; - final accumulatedProblems = []; - for (final packageDir in packages) { - final String packageName = p.basename(packageDir.path); - printer('Dry running publish for $packageName...'); - final ProcessRunnerResult result = await processRunner.runProcess( - ['dart', 'pub', 'publish', '--dry-run'], - workingDirectory: packageDir, - failOk: true, - ); - printer(result.stdout); - if (result.exitCode != 0) { - // Check and see if the problem was actual errors or just warnings, etc. - // Warning output includes "Package has 2 warnings." - // Failed output includes: - // "your package is missing some requirements" - if (result.stderr.contains( - 'your package is missing some requirements', - )) { - accumulatedProblems.add('ERROR: Dry run failed for $packageName'); - dryRunFailed = true; - } else { - accumulatedProblems.add( - 'WARNING: Dry run has some warnings or hints for $packageName', - ); - } - printer(result.stderr); - } else { - accumulatedProblems.add('Dry run for $packageName successful.'); - } - } - printer('--- Dry Run Finished ---'); - printer(accumulatedProblems.join('\n')); - return !dryRunFailed; - } - - Future> _getVersionsToPublish( - List packages, - ) async { - final versionsToPublish = {}; - for (final packageDir in packages) { - final String packageName = p.basename(packageDir.path); - versionsToPublish[packageName] = await getPackageVersion(packageDir); - } - return versionsToPublish; - } - - Future _performPublish(List packages) async { - printer('--- Starting Actual Publish ---'); - for (final packageDir in packages) { - final String packageName = p.basename(packageDir.path); - printer('Publishing $packageName...'); - final ProcessRunnerResult result = await processRunner.runProcess( - ['dart', 'pub', 'publish', '--force'], - workingDirectory: packageDir, - failOk: true, - printOutput: true, - ); - if (result.exitCode != 0) { - throw ReleaseException('Failed to publish $packageName'); - } - printer('$packageName published successfully.'); - } - printer('--- Publish Finished ---'); - } - - Future _createTags(Map versionsToPublish) async { - printer('\n--- Creating Git Tags ---'); - for (final MapEntry entry in versionsToPublish.entries) { - final tagName = '${entry.key}-${entry.value}'; - printer('Creating tag: $tagName'); - final ProcessRunnerResult result = await processRunner.runProcess( - ['git', 'tag', tagName], - workingDirectory: repoRoot, - failOk: true, - ); - if (result.exitCode != 0) { - printer('ERROR: Failed to create tag $tagName'); - printer(result.stderr); - // Don't exit, just warn - } - } - printer('--- Tagging Finished ---'); - printer('\nTo push tags, run: "git push upstream --tags"'); - } - - Future _prepareNextCycle(List packages) async { - printer('\n--- Preparing for next development cycle ---'); - for (final packageDir in packages) { - final String newVersion = await getPackageVersion(packageDir); - var version = Version.parse(newVersion); - await _addNewChangelogSection( - packageDir, - version.nextPatch.canonicalizedVersion, - ); - } - printer('--- Next cycle preparation finished ---'); - } - - Future _addNewChangelogSection( - Directory packageDir, - String newVersion, - ) async { - final String packageName = p.basename(packageDir.path); - - final File changelogFile = fileSystem.file( - p.join(packageDir.path, 'CHANGELOG.md'), - ); - final title = '# `$packageName` Changelog\n'; - String content; - if (!await changelogFile.exists()) { - content = '$title\n## $newVersion (in progress)\n\n'; - await changelogFile.writeAsString(content); - printer('Created and updated CHANGELOG.md in ${packageDir.path}'); - return; - } - - content = await changelogFile.readAsString(); - if (content.contains('(in progress)')) { - printer( - 'CHANGELOG.md in ${packageDir.path} already has an ' - '"in progress" section. Skipping.', - ); - return; - } - List lines = content.split('\n'); - - // Ensure the title is present and correct - if (lines.isEmpty || !lines[0].startsWith('# `$packageName` Changelog')) { - if (lines.isNotEmpty && lines[0].startsWith('# ')) { - lines.removeAt(0); - while (lines.isNotEmpty && lines[0].trim().isEmpty) { - lines.removeAt(0); - } - } - lines.insert(0, title); - } - - // Insert the new entry after the title and any blank lines - var insertIndex = 1; - while (insertIndex < lines.length && lines[insertIndex].trim().isEmpty) { - insertIndex++; - } - - final newEntry = '## $newVersion (in progress)'; - lines.insert(insertIndex, ''); // Blank line before new entry - lines.insert(insertIndex, newEntry); - - await changelogFile.writeAsString(lines.join('\n')); - printer('Added new section to CHANGELOG.md in ${packageDir.path}'); - } -} diff --git a/tool/release/lib/src/utils.dart b/tool/release/lib/src/utils.dart deleted file mode 100644 index a89256786..000000000 --- a/tool/release/lib/src/utils.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:file/file.dart'; -import 'package:path/path.dart' as p; -import 'package:yaml/yaml.dart'; - -const excludedPackages = ['json_schema_builder', 'genai_primitives']; - -Future> findPackages( - Directory repoRoot, - Printer printer, -) async { - final Directory packagesDir = repoRoot.childDirectory('packages'); - if (!await packagesDir.exists()) { - printer('Error: packages directory not found at ${packagesDir.path}'); - return []; - } - - final packages = []; - await for (final FileSystemEntity entity in packagesDir.list()) { - if (entity is Directory) { - final String packageName = p.basename(entity.path); - if (excludedPackages.contains(packageName)) { - printer('Skipping excluded package: $packageName'); - continue; - } - final File pubspecFile = entity.childFile('pubspec.yaml'); - if (await pubspecFile.exists()) { - packages.add(entity); - } - } - } - return packages; -} - -Future getPackageVersion(Directory packageDir) async { - final File pubspecFile = packageDir.childFile('pubspec.yaml'); - final String content = await pubspecFile.readAsString(); - final yamlMap = loadYaml(content) as Map; - return yamlMap['version'] as String; -} - -typedef Printer = void Function(String message); diff --git a/tool/release/pubspec.yaml b/tool/release/pubspec.yaml deleted file mode 100644 index 6a1c7d34c..000000000 --- a/tool/release/pubspec.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2025 The Flutter Authors. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -name: release -description: A tool for managing releases in the genui monorepo. -publish_to: none - -environment: - sdk: ">=3.10.0 <4.0.0" - -resolution: workspace - -dependencies: - args: ^2.7.0 - file: ^7.0.1 - path: ^1.9.1 - process_runner: ^4.2.4 - pub_semver: ^2.2.0 - yaml: ^3.1.3 - -dev_dependencies: - test: ^1.26.2 diff --git a/tool/release/test/bump_test.dart b/tool/release/test/bump_test.dart deleted file mode 100644 index 01a6ad32a..000000000 --- a/tool/release/test/bump_test.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io'; - -import 'package:file/memory.dart'; -import 'package:file/src/interface/directory.dart'; -import 'package:process_runner/process_runner.dart'; -import 'package:process_runner/test/fake_process_manager.dart'; -import 'package:release/release.dart'; -import 'package:test/test.dart'; - -void main() { - group('BumpCommand', () { - late MemoryFileSystem fileSystem; - late FakeProcessManager processManager; - late ReleaseTool releaseTool; - late Directory repoRoot; - late Directory packageADir; - - setUp(() { - fileSystem = MemoryFileSystem(); - repoRoot = fileSystem.systemTempDirectory.createTempSync('genui_repo'); - processManager = FakeProcessManager((input) {}); // Stdin callback - releaseTool = ReleaseTool( - fileSystem: fileSystem, - processRunner: ProcessRunner(processManager: processManager), - repoRoot: repoRoot, - stdinReader: () => null, // Not used in bump tests - printer: (_) {}, - ); - - final Directory packagesDir = repoRoot.childDirectory('packages'); - packagesDir.createSync(recursive: true); - - packageADir = packagesDir.childDirectory('package_a'); - packageADir.createSync(); - packageADir.childFile('pubspec.yaml').writeAsStringSync(''' -name: package_a -version: 1.0.0 -'''); - packageADir.childFile('CHANGELOG.md').writeAsStringSync(''' -## 1.0.0 - -- Initial release. -'''); - - final Directory excludedPackage = packagesDir.childDirectory( - 'json_schema_builder', - ); - excludedPackage.createSync(); - excludedPackage.childFile('pubspec.yaml').writeAsStringSync(''' -name: json_schema_builder -version: 0.1.0 -'''); - }); - - test('should bump patch version and update CHANGELOG', () async { - packageADir.childFile('CHANGELOG.md').writeAsStringSync(''' -# `package_a` Changelog - -## 1.0.1 (in progress) - -- Work in progress. - -## 1.0.0 - -- Initial release. -'''); - processManager.fakeResults = { - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'bump', - 'patch', - ], workingDirectory: packageADir.path): [ - () { - packageADir.childFile('pubspec.yaml').writeAsStringSync(''' -name: package_a -version: 1.0.1 -'''); - return ProcessResult(0, 0, '', ''); - }(), - ], - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'upgrade', - '--major-versions', - ], workingDirectory: repoRoot.path): [ - ProcessResult(0, 0, '', ''), - ], - }; - - await releaseTool.bump('patch'); - - final String pubspecContent = packageADir - .childFile('pubspec.yaml') - .readAsStringSync(); - expect(pubspecContent, contains('version: 1.0.1')); - - final String changelogContent = packageADir - .childFile('CHANGELOG.md') - .readAsStringSync(); - expect( - changelogContent, - startsWith( - '# `package_a` Changelog\n\n## 1.0.1\n\n- Work in progress.', - ), - ); - }); - }); -} diff --git a/tool/release/test/publish_test.dart b/tool/release/test/publish_test.dart deleted file mode 100644 index f34e2bad2..000000000 --- a/tool/release/test/publish_test.dart +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:io'; - -import 'package:file/file.dart'; -import 'package:file/memory.dart'; -import 'package:process_runner/process_runner.dart'; -import 'package:process_runner/test/fake_process_manager.dart'; -import 'package:release/release.dart'; -import 'package:release/src/utils.dart'; -import 'package:test/test.dart'; - -void main() { - group('PublishCommand', () { - late MemoryFileSystem fileSystem; - late FakeProcessManager processManager; - late Directory repoRoot; - late Directory packageADir; - late List fakeStdinLines; - late int stdinReadIndex; - - String? fakeStdinReader() { - if (stdinReadIndex < fakeStdinLines.length) { - return fakeStdinLines[stdinReadIndex++]; - } - return null; - } - - ReleaseTool buildReleaseTool({Printer? printer}) { - return ReleaseTool( - fileSystem: fileSystem, - processRunner: ProcessRunner(processManager: processManager), - repoRoot: repoRoot, - stdinReader: fakeStdinReader, - printer: printer, - ); - } - - setUp(() { - fileSystem = MemoryFileSystem(); - repoRoot = fileSystem.systemTempDirectory.createTempSync('genui_repo'); - processManager = FakeProcessManager((input) {}); // Stdin callback - fakeStdinLines = []; - stdinReadIndex = 0; - - final Directory packagesDir = repoRoot.childDirectory('packages'); - packagesDir.createSync(recursive: true); - - packageADir = packagesDir.childDirectory('package_a'); - packageADir.createSync(); - packageADir.childFile('pubspec.yaml').writeAsStringSync(''' -name: package_a -version: 1.2.3 -'''); - - final Directory excludedPackage = packagesDir.childDirectory( - 'json_schema_builder', - ); - excludedPackage.createSync(); - excludedPackage.childFile('pubspec.yaml').writeAsStringSync(''' -name: json_schema_builder -version: 0.1.0 -'''); - }); - - test( - 'PublishCommand dry run should only call dry-run and print tags', - () async { - final printOutput = []; - final ReleaseTool releaseTool = buildReleaseTool( - printer: printOutput.add, - ); - - processManager.fakeResults = { - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'publish', - '--dry-run', - ], workingDirectory: packageADir.path): [ - ProcessResult(0, 0, '', ''), - ], - }; - - await releaseTool.publish(force: false); - - expect(processManager.invocations.length, 1); - expect(processManager.invocations[0].invocation.skip(1), [ - 'pub', - 'publish', - '--dry-run', - ]); - expect(printOutput.join('\n'), contains('package_a-1.2.3')); - }, - ); - - test('PublishCommand publish --force with yes should publish, tag, and ' - 'update changelog', () async { - fakeStdinLines = ['yes']; - final ReleaseTool releaseTool = buildReleaseTool(printer: (_) {}); - packageADir.childFile('CHANGELOG.md').writeAsStringSync(''' -# `package_a` Changelog - -## 1.2.3 - -- Release version. -'''); - - processManager.fakeResults = { - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'publish', - '--dry-run', - ], workingDirectory: packageADir.path): [ - ProcessResult(0, 0, '', ''), - ], - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'publish', - '--force', - ], workingDirectory: packageADir.path): [ - ProcessResult(0, 0, '', ''), - ], - FakeInvocationRecord(const [ - 'git', - 'tag', - 'package_a-1.2.3', - ], workingDirectory: repoRoot.path): [ - ProcessResult(0, 0, '', ''), - ], - }; - - await releaseTool.publish(force: true); - - expect(processManager.invocations.length, 3); - expect(processManager.invocations[0].invocation.skip(1), [ - 'pub', - 'publish', - '--dry-run', - ]); - expect(processManager.invocations[1].invocation.skip(1), [ - 'pub', - 'publish', - '--force', - ]); - expect(processManager.invocations[2].invocation.skip(1), [ - 'tag', - 'package_a-1.2.3', - ]); - - final String pubspecContent = packageADir - .childFile('pubspec.yaml') - .readAsStringSync(); - expect(pubspecContent, contains('version: 1.2.3')); - - final String changelogContent = packageADir - .childFile('CHANGELOG.md') - .readAsStringSync(); - expect( - changelogContent, - startsWith( - '# `package_a` Changelog\n\n## 1.2.4 (in progress)\n\n## 1.2.3\n\n' - '- Release version.', - ), - ); - }); - - test('PublishCommand publish --force with no should abort', () async { - fakeStdinLines = ['no']; - final ReleaseTool releaseTool = buildReleaseTool(printer: (_) {}); - - processManager.fakeResults = { - FakeInvocationRecord(const [ - 'dart', - 'pub', - 'publish', - '--dry-run', - ], workingDirectory: packageADir.path): [ - ProcessResult(0, 0, '', ''), - ], - }; - - await releaseTool.publish(force: true); - expect(processManager.invocations.length, 1); - expect(processManager.invocations[0].invocation.skip(1), [ - 'pub', - 'publish', - '--dry-run', - ]); - }); - }); -} diff --git a/tool/release/test/release_test.dart b/tool/release/test/release_test.dart deleted file mode 100644 index 62d664c2e..000000000 --- a/tool/release/test/release_test.dart +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2025 The Flutter Authors. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:test/test.dart'; - -import '../bin/release.dart' as app; - -void main() { - group('release.dart CLI', () { - late InMemoryIOSink stdout; - late InMemoryIOSink stderr; - - setUp(() { - stdout = InMemoryIOSink(); - stderr = InMemoryIOSink(); - }); - - test('--help prints usage to stdout', () async { - final int exitCode = await app.run( - ['--help'], - stdout: stdout, - stderr: stderr, - ); - expect(exitCode, 0, reason: 'Exit code should be 0'); - expect( - stdout.toString(), - contains('Usage: dart run tool/release/bin/release.dart'), - reason: 'Stdout should contain usage', - ); - expect( - stdout.toString(), - contains('Print this usage information.'), - reason: 'Stdout should contain help description', - ); - expect(stderr.toString(), isEmpty, reason: 'Stderr should be empty'); - }); - - test('help command prints usage to stdout', () async { - final int exitCode = await app.run( - ['help'], - stdout: stdout, - stderr: stderr, - ); - expect(exitCode, 0); - expect( - stdout.toString(), - contains('Usage: dart run tool/release/bin/release.dart'), - ); - expect(stderr.toString(), isEmpty); - }); - - test('no arguments prints usage to stderr and exits with 1', () async { - final int exitCode = await app.run([], stdout: stdout, stderr: stderr); - expect(exitCode, 1); - expect( - stderr.toString(), - contains('Usage: dart run tool/release/bin/release.dart'), - ); - expect(stdout.toString(), isEmpty); - }); - - test('unknown command prints usage to stderr and exits with 1', () async { - final int exitCode = await app.run( - ['unknown'], - stdout: stdout, - stderr: stderr, - ); - expect(exitCode, 1); - expect( - stderr.toString(), - contains('Usage: dart run tool/release/bin/release.dart'), - ); - }); - - test('help unknown_command prints error to stderr', () async { - final int exitCode = await app.run( - ['help', 'unknown'], - stdout: stdout, - stderr: stderr, - ); - expect(exitCode, 1); - expect(stderr.toString(), contains('Unknown command: unknown')); - expect( - stderr.toString(), - contains('Usage: dart run tool/release/bin/release.dart'), - ); - }); - }); -} - -class InMemoryIOSink implements IOSink { - final StringBuffer _buffer = StringBuffer(); - final Completer _doneCompleter = Completer(); - - @override - Encoding encoding = utf8; - - @override - void add(List data) { - _buffer.write(encoding.decode(data)); - } - - @override - void addError(Object error, [StackTrace? stackTrace]) { - _buffer.writeln('Error: $error'); - } - - @override - Future addStream(Stream> stream) async { - await for (final chunk in stream) { - add(chunk); - } - } - - @override - Future close() async { - _doneCompleter.complete(); - } - - @override - Future get done => _doneCompleter.future; - - @override - Future flush() async {} - - @override - void write(Object? object) { - _buffer.write(object); - } - - @override - void writeAll(Iterable objects, [String separator = '']) { - _buffer.writeAll(objects, separator); - } - - @override - void writeCharCode(int charCode) { - _buffer.writeCharCode(charCode); - } - - @override - void writeln([Object? object = '']) { - _buffer.writeln(object); - } - - @override - String toString() => _buffer.toString(); -} From 7e1c65e7e1b3e1ba84e82528dba979e6aa1385b2 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:56:11 -0700 Subject: [PATCH 31/32] Update pubspec.yaml --- pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index ea45f65a1..2607aad4d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,7 +24,6 @@ workspace: - tool/e2e - tool/fix_copyright - - tool/release - tool/test_and_fix flutter: From 83653cc8a9a971d867d942024b0b2d56b534d2ec Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Sat, 16 May 2026 15:57:35 -0700 Subject: [PATCH 32/32] Update docs/contributing/publishing.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docs/contributing/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/publishing.md b/docs/contributing/publishing.md index 30a4830b4..d41109888 100644 --- a/docs/contributing/publishing.md +++ b/docs/contributing/publishing.md @@ -11,7 +11,7 @@ There are two CI workflows that enable this automation: ## Passing the publish / validate job -In general, the job [publish / validate](https://github.com/flutter/genui/actions/runs/25936562918) checks if all pub.dev packages are ready for publishing. +In general, the job [publish / validate](https://github.com/flutter/genui/actions/workflows/post_summaries.yaml) checks if all pub.dev packages are ready for publishing. To make sure your PR passes this validation, follow [firehose rules](https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose).