Files
T
Eligio Mariño 792b91c445 ci: test windows image (#339)
- **`windows.Dockerfile`** — fixes the `COPY` source path from
`./test/Windows.Tests.ps1` to `./test/windows/Windows.Tests.ps1` (root
cause of the 12-month "in_progress forever" state); adds `COPY
./config/version.json` to the `test` stage; replaces the commented `CMD`
with a real `CMD` so `docker run`/`docker compose run` invokes Pester
without arguments.
- **`test/windows/Windows.Tests.ps1`** — fixes the `VC.CMake.Project`
pattern typo (`,versiona*` → `,version=*`) and standardises all three
VS-component patterns to `,version=*`; adds a `Flutter version` test
that reads `config/version.json` and asserts `flutter --version` inside
the container reports the same version; adds a `Flutter doctor` test
with a per-line parser (skip disabled platforms, fail on any non-`[✓]`
for Windows toolchain lines, fail on `[✗]` elsewhere).
- **`script/RunPester.ps1`** — forces `[Console]::OutputEncoding = UTF8`
so the `[✓]`/`[!]`/`[✗]` doctor glyphs survive the `windows-2025`
runner's default OEM codepage.
- **`test/windows/`** — deletes the dead `ory/dockertest` Go skeleton
(`main.go`, `main_test.go`, `go.mod`, `go.sum`) that was never wired
into CI and had its only meaningful assertion commented out.
- **`.github/workflows/windows.yml`** — deletes three commented-out
blocks (`Scan with Docker Scout`, `Push to Docker Hub`,
`validate_version` job referencing the deleted `config/version.cue`);
drops the now-unused elevated permissions (`packages: write`,
`pull-requests: write`, `security-events: write`).

---------

Co-authored-by: verified-commit[bot] <180343340+verified-commit[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 16:15:33 +02:00

4.5 KiB

ADDED Requirements

Requirement: Tag push publishes a flutter-windows image to all release registries

When a tag matching * is pushed to the repository, the release_windows job in .github/workflows/release.yml SHALL build windows.Dockerfile with --target flutter and --build-arg flutter_version=<tag>, and SHALL push the resulting image to Docker Hub, GitHub Container Registry, and Quay.io under the repository name flutter-windows with the tag equal to the Flutter version.

The experience context is the CI engineer who, on the day a new Flutter stable lands, expects to run docker pull docker.io/<org>/flutter-windows:<version> and find the image at the same tag they already use for flutter-android.

Scenario: Tag push fans out to all three registries

  • GIVEN a tag X.Y.Z is pushed to the repository
  • WHEN the release_windows job completes successfully
  • THEN docker.io/<org>/flutter-windows:X.Y.Z exists
  • AND ghcr.io/<org>/flutter-windows:X.Y.Z exists
  • AND quay.io/<org>/flutter-windows:X.Y.Z exists

Scenario: Tag-image consistency

  • WHEN any of the three published flutter-windows:X.Y.Z images is pulled and flutter --version is invoked inside it
  • THEN the reported Flutter version is exactly X.Y.Z

Requirement: Windows release runs in parallel with Android release

The release_windows job SHALL NOT declare a needs: dependency on release_android, and release_android SHALL NOT declare a needs: dependency on release_windows. A failure in one SHALL NOT cancel the other.

The experience context is the maintainer cutting a release: they accept that one architecture may publish while the other fails, and prefer fixing the failed one in a follow-up tag rather than blocking both.

Scenario: Android publishes when Windows build fails

  • GIVEN a tag is pushed
  • AND the release_windows job fails (e.g., transient windows-2025 runner issue)
  • AND the release_android job succeeds
  • WHEN the workflow run completes
  • THEN Android images are published at all three registries
  • AND the workflow run is reported as failed (because at least one job failed)
  • AND the failure surface is the release_windows job specifically, not release_android

Requirement: Windows release uses the same metadata conventions as Android release

The release_windows job SHALL use docker/metadata-action with the images input set to the same three registry namespaces and the tags input set to type=raw,value=${{ env.FLUTTER_VERSION }}, mirroring the Android job. The image labels (org.opencontainers.image.*) produced by metadata-action SHALL be applied to the built image via docker/build-push-action's labels input.

The experience context is the operator inspecting docker inspect <org>/flutter-windows:X.Y.Z and docker inspect <org>/flutter-android:X.Y.Z and finding the same set of OCI labels (description, source, revision, version) populated with the same values.

Scenario: Labels match Android conventions

  • GIVEN a successful release_windows run for tag X.Y.Z
  • WHEN an operator runs docker inspect docker.io/<org>/flutter-windows:X.Y.Z and inspects the Labels map
  • THEN the keys org.opencontainers.image.source, org.opencontainers.image.revision, org.opencontainers.image.version, and org.opencontainers.image.title are all present
  • AND org.opencontainers.image.version equals X.Y.Z
  • AND org.opencontainers.image.revision equals the commit SHA of the tag

Requirement: Manual workflow_dispatch rebuild remains available for Windows

The release.yml workflow SHALL continue to declare workflow_dispatch:, and the release_windows job SHALL be runnable via workflow_dispatch with the FLUTTER_VERSION env var set from github.ref_name, so that a maintainer can rebuild a single tag's Windows image without re-cutting the Git tag.

The experience context is the maintainer recovering from a transient Windows runner failure: they re-run the workflow on the existing tag instead of force-pushing a new one.

Scenario: Manual rebuild produces a fresh image

  • GIVEN a tag X.Y.Z exists in the repository
  • AND the prior release_windows run for that tag failed
  • WHEN a maintainer triggers release.yml via workflow_dispatch selecting ref X.Y.Z
  • THEN release_windows builds and pushes flutter-windows:X.Y.Z to all three registries
  • AND the existing image digests at those tags are overwritten by the new digests