Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/update_flutter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright 2026 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

name: Update Flutter SDK Pin

on:
schedule:
- cron: '0 0 * * 1' # Run every Monday at midnight UTC
workflow_dispatch: # Allow manual execution from the Actions tab

permissions:
contents: write
pull-requests: write

jobs:
check-and-update:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Check for New Flutter stable version
id: check-version
run: |
# 1. Retrieve the current pinned version from the shared script
CURRENT_VERSION=$(grep -E 'FLUTTER_VERSION="[0-9.]+"' tool/provision_flutter.sh | head -n 1 | cut -d'"' -f2)
echo "Current pinned version: $CURRENT_VERSION"

# 2. Retrieve the latest stable version from Flutter's official releases manifest
LATEST_VERSION=$(curl -s https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json | jq -r '.current_release.stable')
echo "Latest stable version: $LATEST_VERSION"

# 3. Compare and update if a newer version is available
if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
echo "New Flutter stable version detected: $LATEST_VERSION"
sed -i -e "s/FLUTTER_VERSION=\"$CURRENT_VERSION\"/FLUTTER_VERSION=\"$LATEST_VERSION\"/g" tool/provision_flutter.sh
echo "updated=true" >> $GITHUB_OUTPUT
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
else
echo "Flutter SDK is already up to date."
echo "updated=false" >> $GITHUB_OUTPUT
fi

- name: Create Pull Request for Version Bump
if: steps.check-version.outputs.updated == 'true'
uses: peter-evans/create-pull-request@v6
with:
commit-message: "ci: bump pinned Flutter SDK to version ${{ steps.check-version.outputs.latest_version }}"
title: "ci: bump pinned Flutter SDK to version ${{ steps.check-version.outputs.latest_version }}"
body: |
An automated check has detected a new stable release of the Flutter SDK.

* **New Pinned Version**: `${{ steps.check-version.outputs.latest_version }}`

This Pull Request updates our shared provisioning script (`tool/provision_flutter.sh`) to target this version. All presubmit tests will be run against this version to verify compatibility.
branch: "auto-update-flutter-sdk"
delete-branch: true
labels: |
dependencies
ci
79 changes: 79 additions & 0 deletions testSrc/unit/io/flutter/CIIntegrityTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2026 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package io.flutter;

import org.junit.Test;
import java.io.File;
import java.nio.file.Files;
import java.util.regex.Pattern;
import static org.junit.Assert.assertTrue;

/**
* Integrity tests for the CI/CD automation pipeline.
* <p>
* <b>Why this exists:</b>
* Our CI/CD scripts rely on a shared bash script to provision the Flutter SDK, and a
* scheduled GitHub Actions workflow to automatically check for new Flutter stable releases
* and submit version-bumping Pull Requests.
* <p>
* If a developer modifies the provisioning script (e.g., renaming the constant FLUTTER_VERSION)
* or alters the regex search format without updating the GitHub Actions workflow, the automation
* will fail silently in production.
* <p>
* This class acts as a "meta-test" or "integrity-check" that runs during standard project
* compilations (`./gradlew test`) to give developers an immediate early warning of synchronization
* failures before code is merged.
*/
public class CIIntegrityTest {

/**
* Verifies that the Flutter SDK provisioning script exists at the expected path
* and defines the `FLUTTER_VERSION` constant in the exact semver format required.
* <p>
* If this test fails, it means `tool/provision_flutter.sh` was moved, deleted, or
* the `FLUTTER_VERSION` constant definition was formatted incorrectly (or renamed).
*/
@Test
public void testFlutterProvisioningScriptIntegrity() throws Exception {
// The JVM's Current Working Directory (CWD) during unit tests is the repository root.
File scriptFile = new File("tool/provision_flutter.sh");
assertTrue("provision_flutter.sh must exist at the repository root 'tool/' directory", scriptFile.exists());

String content = Files.readString(scriptFile.toPath());

// Ensure the shell script declares the version constant in a predictable pattern:
// E.g. FLUTTER_VERSION="3.41.0"
Pattern versionPattern = Pattern.compile("FLUTTER_VERSION=\"\\d+\\.\\d+\\.\\d+\"");
assertTrue(
"provision_flutter.sh must define a constant FLUTTER_VERSION matching semver format (e.g., FLUTTER_VERSION=\"3.41.0\"). " +
"This constant is critical because the automated GitHub Actions updater searches for this exact pattern to bump the version.",
versionPattern.matcher(content).find()
);
Comment thread
pq marked this conversation as resolved.
Outdated
}

/**
* Verifies that the automated GitHub Actions updater workflow is synchronized
* with the provisioning script.
* <p>
* Specifically, it ensures the workflow searches for the exact constant pattern
* `FLUTTER_VERSION="[0-9.]+"` to perform its automated string replacement. If a developer
* renames the constant in the script, they MUST also update the workflow, otherwise this test fails.
*/
@Test
public void testGitHubWorkflowRegexSync() throws Exception {
File workflowFile = new File(".github/workflows/update_flutter.yaml");
assertTrue("update_flutter.yaml workflow must exist in the '.github/workflows/' directory", workflowFile.exists());

String content = Files.readString(workflowFile.toPath());

// The workflow must use the exact same constant name in its grep/sed matching regex
assertTrue(
"update_flutter.yaml must reference the 'FLUTTER_VERSION=\"[0-9.]+\"' constant in its search-and-replace step. " +
"If you renamed this constant in tool/provision_flutter.sh, you must also update it inside update_flutter.yaml.",
content.contains("FLUTTER_VERSION=\"[0-9.]+\"")
Comment thread
pq marked this conversation as resolved.
Outdated
);
}
}
2 changes: 1 addition & 1 deletion tool/provision_flutter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set -e
# Provision the pinned Flutter SDK if not present
if [ ! -d "../flutter" ]; then
OS_NAME=$(uname -s | tr '[:upper:]' '[:lower:]')
FLUTTER_VERSION="3.41.0"
FLUTTER_VERSION="3.22.0"

echo "Provisioning Flutter SDK version ${FLUTTER_VERSION} for ${OS_NAME}..."
if [ "$OS_NAME" = "darwin" ]; then
Expand Down
Loading