Files
flutter-docker-image/.github/workflows/update_version.yml
T
Eligio Mariño 008cce50a1 feat: pin Windows toolchain versions in config/version.json (#456)
- Extends the manifest-first discipline (already used for
Flutter/Android) to the Windows toolchain. `config/version.json` now
carries `windows.git`, `windows.vsBuildTools.cmakeProject`,
`windows.vsBuildTools.windows11Sdk.build`, and
`windows.vsBuildTools.vcTools`; `config/schema.cue` validates them via
new `#SemverQuad` and `#WindowsToolchain` definitions.

---------

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

442 lines
19 KiB
YAML

on:
schedule:
- cron: '0 0 * * MON-FRI'
workflow_dispatch:
# Declare default permissions as read only.
permissions:
contents: read
env:
FLUTTER_VERSION_PATH: config/flutter_version.json
jobs:
# Resolves the bootstrap container tag — the latest published release tag.
setup:
runs-on: ubuntu-24.04
outputs:
flutter_version: ${{ steps.read.outputs.version }}
steps:
- name: Read latest release tag
id: read
env:
GH_TOKEN: ${{ github.token }}
run: |
version=$(gh api "repos/${{ github.repository }}/releases/latest" --jq '.tag_name')
echo "version=$version" >> "$GITHUB_OUTPUT"
update_flutter_version:
permissions:
# Allow to write contents to push commits
contents: write
# Allow to write pull requests to push commits and write comments
pull-requests: write
runs-on: ubuntu-24.04
outputs:
new_version: ${{ steps.update_flutter_version.outputs.result }}
flutter_version_artifact_id: ${{ steps.upload-version.outputs.artifact-id }}
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup CUE
uses: jaxxstorm/action-install-gh-release@6096f2a2bbfee498ced520b6922ac2c06e990ed2 # v2.1.0
with:
repo: cue-lang/cue
tag: v0.15.0
digest: 06925fc1e5174591cef0b1e42ac32cff4271804742cd20893de1793b6d82d460
- name: Fetch and update latest Flutter version
id: update_flutter_version
run: |
releases_json_path="${RUNNER_TEMP}/releases.json"
curl -fsSL https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json \
-o "$releases_json_path"
old_version=$(jq -r '.flutter.version' "${{ env.FLUTTER_VERSION_PATH }}")
new_version=$(jq -r '[.releases[] | select(.channel=="stable")] | max_by(.release_date) | .version' "$releases_json_path")
new_channel=$(jq -r '[.releases[] | select(.channel=="stable")] | max_by(.release_date) | .channel' "$releases_json_path")
new_commit=$(jq -r '[.releases[] | select(.channel=="stable")] | max_by(.release_date) | .hash' "$releases_json_path")
echo "Current pinned version: $old_version"
echo "Latest upstream stable version: $new_version (channel: $new_channel)"
if [ "$old_version" = "$new_version" ]; then
echo "No version change — skipping update."
echo "result=false" >> "$GITHUB_OUTPUT"
else
echo "New version detected — updating ${{ env.FLUTTER_VERSION_PATH }}"
printf '{\n "flutter": {\n "channel": "%s",\n "commit": "%s",\n "version": "%s"\n }\n}\n' \
"$new_channel" "$new_commit" "$new_version" > "${{ env.FLUTTER_VERSION_PATH }}"
echo "result=true" >> "$GITHUB_OUTPUT"
fi
- name: Validate version.json with CUE
if: ${{ steps.update_flutter_version.outputs.result == 'true' }}
run: cue vet config/schema.cue -d '#FlutterVersion' ${{ env.FLUTTER_VERSION_PATH }}
- name: Upload artifact with the new Flutter version
if: ${{ steps.update_flutter_version.outputs.result == 'true' }}
id: upload-version
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: flutter_version.json
path: ${{ env.FLUTTER_VERSION_PATH }}
update_windows_version:
permissions:
contents: write
needs: update_flutter_version
if: ${{ needs.update_flutter_version.outputs.new_version == 'true' }}
outputs:
version_artifact_id: ${{ steps.upload-version.outputs.artifact-id }}
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup CUE
uses: jaxxstorm/action-install-gh-release@6096f2a2bbfee498ced520b6922ac2c06e990ed2 # v2.1.0
with:
repo: cue-lang/cue
tag: v0.15.0
digest: 06925fc1e5174591cef0b1e42ac32cff4271804742cd20893de1793b6d82d460
# Parallel pattern with update_android_version: the artifact is downloaded
# to keep job structure symmetric, even though windows fields are not
# currently tied to a specific Flutter tag.
- name: Delete flutter_version.json
run: rm ${{ env.FLUTTER_VERSION_PATH }}
- name: Download artifact with the new Flutter version
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.update_flutter_version.outputs.flutter_version_artifact_id }}
path: config
- name: Resolve latest Git for Windows version
id: git_version
run: |
tag=$(curl -fsSL https://api.github.com/repos/git-for-windows/git/releases/latest | jq -r '.tag_name')
version=${tag#v}
version=${version%.windows.*}
echo "git_version=$version" >> "$GITHUB_OUTPUT"
echo "Resolved Git for Windows version: $version"
- name: Fetch VS channel manifest
run: curl -fsSL https://aka.ms/vs/17/release/channel -o channel.json
# The channel manifest only contains product-level entries; per-component
# versions live in VisualStudio.vsman, referenced and SHA-256 pinned from
# the channel via the Microsoft.VisualStudio.Manifests.VisualStudio item.
- name: Resolve VS catalog manifest payload
id: vsman_payload
run: |
url=$(jq -r '.channelItems[] | select(.id=="Microsoft.VisualStudio.Manifests.VisualStudio") | .payloads[0].url' channel.json)
sha=$(jq -r '.channelItems[] | select(.id=="Microsoft.VisualStudio.Manifests.VisualStudio") | .payloads[0].sha256' channel.json)
echo "url=$url" >> "$GITHUB_OUTPUT"
echo "sha=$sha" >> "$GITHUB_OUTPUT"
- name: Download and verify VS catalog manifest
run: |
curl -fsSL "${{ steps.vsman_payload.outputs.url }}" -o vsman.json
echo "${{ steps.vsman_payload.outputs.sha }} vsman.json" | sha256sum -c -
- name: Resolve VS BuildTools component versions
id: vs_versions
run: |
cmake=$(jq -r '.packages[] | select(.id=="Microsoft.VisualStudio.Component.VC.CMake.Project") | .version' vsman.json)
vctools=$(jq -r '.packages[] | select(.id=="Microsoft.VisualStudio.Workload.VCTools") | .version' vsman.json)
echo "cmake=$cmake" >> "$GITHUB_OUTPUT"
echo "vctools=$vctools" >> "$GITHUB_OUTPUT"
echo "CMake: $cmake; VCTools: $vctools"
- name: Write windows block into config/version.json
env:
GIT_VERSION: ${{ steps.git_version.outputs.git_version }}
VS_CMAKE_VERSION: ${{ steps.vs_versions.outputs.cmake }}
VS_VCTOOLS_VERSION: ${{ steps.vs_versions.outputs.vctools }}
run: |
# Win11SDK build id is human-pinned (changes infrequently; tied to OS branding).
win11sdk_build=$(jq -r '.windows.vsBuildTools.windows11Sdk.build' config/version.json)
jq --arg git "$GIT_VERSION" \
--arg cmake "$VS_CMAKE_VERSION" \
--arg vctools "$VS_VCTOOLS_VERSION" \
--argjson sdkbuild "$win11sdk_build" \
'.windows = {
git: {version: $git},
vsBuildTools: {
cmakeProject: {version: $cmake},
windows11Sdk: {build: $sdkbuild},
vcTools: {version: $vctools}
}
}' config/version.json > config/version.json.tmp
mv config/version.json.tmp config/version.json
- name: Validate version.json with CUE
run: cue vet config/schema.cue -d '#Version' config/version.json
# The artifact's file is renamed so it doesn't collide with the Android
# artifact's version.json in update_docs_and_create_pr's merge step.
- name: Stage windows-only artifact
run: cp config/version.json "${RUNNER_TEMP}/version.json.windows"
- name: Upload artifact with the updated windows block
id: upload-version
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: version.json.windows
path: ${{ runner.temp }}/version.json.windows
- name: Upload VS manifest artifacts for forensics
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: vs-manifests
path: |
channel.json
vsman.json
update_android_version:
permissions:
# Allow to write contents to push commits
contents: write
# Allow to read packages to pull the container image from GitHub Container Registry
packages: read
# Allow to write pull requests to create a pull request
pull-requests: write
needs: [setup, update_flutter_version]
if: ${{ needs.update_flutter_version.outputs.new_version == 'true' }}
outputs:
version_artifact_id: ${{ steps.upload-version.outputs.artifact-id }}
android_test_artifact_id: ${{ steps.upload-android-test.outputs.artifact-id }}
runs-on: ubuntu-24.04
container:
image: ghcr.io/${{ github.repository_owner }}/flutter-android:${{ needs.setup.outputs.flutter_version }}
credentials:
username: ${{ github.actor }}
password: ${{ github.token }}
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# TODO: Workaround because actions/download-artifact can't overwrite existing files
# Check if this workaround can be removed after the following issues are fixed:
# https://github.com/actions/download-artifact/issues/225
# https://github.com/actions/download-artifact/issues/138
- name: Delete flutter_version.json
run: rm ${{ env.FLUTTER_VERSION_PATH }}
- name: Download artifact with the new Flutter version
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.update_flutter_version.outputs.flutter_version_artifact_id }}
path: config
- name: Copy Flutter version into version manifest and export FLUTTER_* environment variables
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const script = require('./script/copyFlutterVersion.js')
await script({core})
- name: Update latest Fastlane version
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const script = require('./script/updateFastlaneVersion.js')
await script({core, fetch})
- name: Update Android SDK build tools version
id: build_tools
run: |
build_tools_version=$(curl -fsSL https://raw.githubusercontent.com/flutter/flutter/refs/tags/${{ env.FLUTTER_VERSION }}/engine/src/flutter/tools/android_sdk/packages.txt | grep 'build-tools' | awk -F'[;:]' '{print $2}')
echo "build_tools_version=$build_tools_version" >>"$GITHUB_OUTPUT"
echo "Build tools version: $build_tools_version"
- name: Setup Flutter
run: |
cd $FLUTTER_ROOT
git fetch origin ${{ env.FLUTTER_VERSION }}:${{ env.FLUTTER_VERSION }}
git switch --discard-changes ${{ env.FLUTTER_VERSION }}
# TODO: Create test app in specific folder with step id, to allow parallel execution
- name: Create test application
run: |
flutter create test_app
# TODO: Cache gradle https://github.com/gradle/gradle-build-action
- name: Update default Android platform versions in Flutter
working-directory: test_app/android
env:
BUILD_TOOLS_VERSION: ${{ steps.build_tools.outputs.build_tools_version }}
run: |
cat ../../script/updateAndroidVersions.gradle.kts >> app/build.gradle.kts
./gradlew --warning-mode all updateAndroidVersions
- name: Clean test application
run: |
rm -rf test_app
- name: Setup CUE
uses: jaxxstorm/action-install-gh-release@6096f2a2bbfee498ced520b6922ac2c06e990ed2 # v2.1.0
with:
repo: cue-lang/cue
tag: v0.15.0
digest: 06925fc1e5174591cef0b1e42ac32cff4271804742cd20893de1793b6d82d460
- name: Generate test files with CUE
run: |
./script/update_test.sh
- name: Upload artifact with the updated version.json
id: upload-version
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: version.json
path: config/version.json
- name: Upload the test artifact for Android
id: upload-android-test
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: android.yml
path: test/android.yml
validate_config_version:
needs: update_android_version
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# TODO: Workaround because actions/download-artifact can't overwrite existing files
# Check if this workaround can be removed after the following issues are fixed:
# https://github.com/actions/download-artifact/issues/225
# https://github.com/actions/download-artifact/issues/138
- name: Delete version.json
run: rm config/version.json
- name: Download artifact with the new Flutter version
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.update_android_version.outputs.version_artifact_id }}
path: config
- name: Setup CUE
uses: jaxxstorm/action-install-gh-release@6096f2a2bbfee498ced520b6922ac2c06e990ed2 # v2.1.0
with:
repo: cue-lang/cue
tag: v0.15.0
digest: 06925fc1e5174591cef0b1e42ac32cff4271804742cd20893de1793b6d82d460
- name: Validate version.json with CUE
run: cue vet config/schema.cue -d '#Version' config/version.json
update_docs_and_create_pr:
needs:
- update_flutter_version
- update_android_version
- update_windows_version
- validate_config_version
runs-on: ubuntu-24.04
env:
IMAGE_REPOSITORY_NAME: flutter-android
VERSION_MANIFEST: config/version.json
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# TODO: Workaround because actions/download-artifact can't overwrite existing files
# Check if this workaround can be removed after the following issues are fixed:
# https://github.com/actions/download-artifact/issues/225
# https://github.com/actions/download-artifact/issues/138
- name: Delete flutter_version.json and version.json
run: |-
rm ${{ env.FLUTTER_VERSION_PATH }} config/version.json test/android.yml
- name: Download configuration artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.update_flutter_version.outputs.flutter_version_artifact_id }},${{ needs.update_android_version.outputs.version_artifact_id }},${{ needs.update_windows_version.outputs.version_artifact_id }}
path: config
# Download to the configured path instead of separated directories by artifact id.
# Artifacts contain distinct filenames (flutter_version.json, version.json,
# version.json.windows) so merge-multiple is safe.
merge-multiple: true
# Merge order: the Android artifact's version.json is the base (it carries
# the new flutter and android blocks). The Windows artifact's windows block
# overlays the windows field. This keeps each producer authoritative over
# its own block.
- name: Merge windows block into version.json
run: |
jq -s '.[0] + {windows: .[1].windows}' config/version.json config/version.json.windows > config/version.json.merged
mv config/version.json.merged config/version.json
rm config/version.json.windows
- name: Setup CUE
uses: jaxxstorm/action-install-gh-release@6096f2a2bbfee498ced520b6922ac2c06e990ed2 # v2.1.0
with:
repo: cue-lang/cue
tag: v0.15.0
digest: 06925fc1e5174591cef0b1e42ac32cff4271804742cd20893de1793b6d82d460
- name: Validate merged version.json with CUE
run: cue vet config/schema.cue -d '#Version' config/version.json
- name: Download test artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
artifact-ids: ${{ needs.update_android_version.outputs.android_test_artifact_id }}
path: test
- name: Setup NodeJS
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
cache: npm
cache-dependency-path: docs/src/package-lock.json
node-version: lts/*
- name: Update documentation
working-directory: docs/src
run: |
npm ci --prefer-offline
npm run build
- name: Read environment variables from the version manifest
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
IMAGE_REPOSITORY_NAME: ${{ env.IMAGE_REPOSITORY_NAME }}
VERSION_MANIFEST: ${{ env.VERSION_MANIFEST }}
with:
script: |
const script = require('./script/setEnvironmentVariables.js')
return await script({ core })
- name: Create commit message variable
id: create_commit_message
run: |
commit_message="chore(release): upgrade flutter to ${{ env.FLUTTER_VERSION }}"
echo "commit_message=$commit_message" >> "$GITHUB_OUTPUT"
echo "Commit message: $commit_message"
- name: Generate authentication token with GitHub App to trigger Actions
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
id: app-token
with:
app-id: ${{ secrets.VERIFIED_COMMIT_ID }}
private-key: ${{ secrets.VERIFIED_COMMIT_KEY }}
repositories: ${{ github.event.repository.name }}
owner: ${{ github.repository_owner }}
# TODO: Generate changelog for the new flutter version, that will be the new tag
- name: Create pull request if there are changes
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11
with:
commit-message: ${{ steps.create_commit_message.outputs.commit_message }}
branch: update-flutter-dependencies/${{ env.FLUTTER_VERSION }}
sign-commits: true
title: ${{ steps.create_commit_message.outputs.commit_message }}
token: ${{ steps.app-token.outputs.token }}