Experiment with a files-changed.json per PR (#161788)

This is an experiment to determine what the wall time of a (minimal)
"upload a JSON file describing files changed".

We are looking for this to take (low) single digit minutes, because if
we use this file (and expand it to become a build plan), it will block
almost _all_ other actions, and will likely get longer as we add more
complex logic and checks. Here's hoping!
This commit is contained in:
Matan Lurey 2025-01-22 12:22:30 -08:00 committed by GitHub
parent 2d3beadffe
commit cc9c13e009
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 118 additions and 9 deletions

37
.github/workflows/files-changed.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Generate Changed Files JSON
on:
pull_request:
types:
- opened
- synchronize
jobs:
generate-json:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Fetch base commit and origin/master
# Fetch what to compare the commit against
run: |
git fetch --no-tags --prune --depth=1 origin ${{ github.event.pull_request.base.sha }}
git fetch --no-tags --prune --depth=1 origin master
echo "FLUTTER_ENGINE_VERSION=${{ github.event.pull_request.base.sha }}" >> "$GITHUB_ENV"
- name: Initialize Dart SDK
# This downloads the version of the Dart SDK for the current platform.
run: |
./bin/dart --version
cd dev/tools && ../../bin/dart pub get
- name: Write changed files to a JSON file
run: |
./bin/dart run dev/tools/bin/get_files_changed.dart --since="${{ github.event.pull_request.base.sha }}" > changed_files.json
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: changed-files
path: changed_files.json

View File

@ -14,10 +14,24 @@
set -e
# Allow overriding the intended engine version via FLUTTER_ENGINE_VERSION.
#
# This is for systems, such as Github Actions, where we know ahead of time the
# base-ref we want to use (to download the engine binaries and avoid trying
# to compute one below).
#
# This environment variable is EXPERIMENTAL. If you are not on the Flutter infra
# team, this code path might be removed at anytime and cease functioning. Please
# file an issue if you have workflow needs.
if [ -n "${FLUTTER_ENGINE_VERSION}" ]; then
ENGINE_VERSION="${FLUTTER_ENGINE_VERSION}"
echo "[Unstable] Override: Setting engine SHA to $ENGINE_VERSION" 1>&2
fi
FLUTTER_ROOT="$(dirname "$(dirname "$(dirname "${BASH_SOURCE[0]}")")")"
# Test for fusion repository
if [ -f "$FLUTTER_ROOT/DEPS" ] && [ -f "$FLUTTER_ROOT/engine/src/.gn" ]; then
# Test for fusion repository and no environment variable override.
if [ -z "$ENGINE_VERSION" ] && [ -f "$FLUTTER_ROOT/DEPS" ] && [ -f "$FLUTTER_ROOT/engine/src/.gn" ]; then
BRANCH=$(git -C "$FLUTTER_ROOT" rev-parse --abbrev-ref HEAD)
# In a fusion repository; the engine.version comes from the git hashes.
if [ -z "${LUCI_CONTEXT}" ]; then
@ -35,14 +49,14 @@ if [ -f "$FLUTTER_ROOT/DEPS" ] && [ -f "$FLUTTER_ROOT/engine/src/.gn" ]; then
else
ENGINE_VERSION=$(git -C "$FLUTTER_ROOT" rev-parse HEAD)
fi
fi
if [[ "$BRANCH" != "stable" && "$BRANCH" != "beta" ]]; then
# Write the engine version out so downstream tools know what to look for.
echo $ENGINE_VERSION > "$FLUTTER_ROOT/bin/internal/engine.version"
if [[ "$BRANCH" != "stable" && "$BRANCH" != "beta" ]]; then
# Write the engine version out so downstream tools know what to look for.
echo $ENGINE_VERSION > "$FLUTTER_ROOT/bin/internal/engine.version"
# The realm on CI is passed in.
if [ -n "${FLUTTER_REALM}" ]; then
echo $FLUTTER_REALM > "$FLUTTER_ROOT/bin/internal/engine.realm"
fi
# The realm on CI is passed in.
if [ -n "${FLUTTER_REALM}" ]; then
echo $FLUTTER_REALM > "$FLUTTER_ROOT/bin/internal/engine.realm"
fi
fi

View File

@ -0,0 +1 @@
This is a stub-file that can be deleted.

View File

@ -0,0 +1,57 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'dart:io' as io;
import 'package:args/args.dart';
final ArgParser _argParser =
ArgParser()
..addOption(
'since',
help: 'What previous SHA to compare the current git state to.',
defaultsTo: 'HEAD^',
)
..addOption(
'output',
help: 'What format to output in.',
defaultsTo: io.stdout.hasTerminal ? 'text' : 'json',
allowed: <String>['text', 'json'],
);
void main(List<String> args) async {
final ArgResults argResults = _argParser.parse(args);
// Get a list of files changed between this commit and the base SHA.
final List<String> filesChanged;
{
final List<String> args = <String>[
'diff',
'--name-only',
'--full-index',
argResults.option('since')!,
];
final io.ProcessResult git = await io.Process.run('git', args);
if (git.exitCode != 0) {
io.stderr.writeln('$args failed (exit code: ${git.exitCode}):');
io.stderr.writeln(git.stdout);
io.stderr.writeln(git.stderr);
io.exitCode = 1;
return;
}
final String stdout = git.stdout as String;
filesChanged = const LineSplitter().convert(stdout);
}
// Output to stdout.
final _Output output = _Output.values.byName(argResults.option('output')!);
io.stdout.writeln(switch (output) {
_Output.text => filesChanged.join('\n'),
_Output.json => jsonEncode(filesChanged),
});
}
enum _Output { text, json }