Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
aac5e95a
Unverified
Commit
aac5e95a
authored
Jun 27, 2022
by
Christopher Fujino
Committed by
GitHub
Jun 27, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] refactor packages_autoroller.dart script (#106580)
parent
28d271ec
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
443 additions
and
29 deletions
+443
-29
analyze.dart
dev/bots/analyze.dart
+1
-1
packages_autoroller
dev/conductor/bin/packages_autoroller
+1
-1
packages_autoroller.dart
dev/conductor/core/bin/packages_autoroller.dart
+30
-10
packages_autoroller.dart
dev/conductor/core/lib/src/packages_autoroller.dart
+88
-14
packages_autoroller_test.dart
dev/conductor/core/test/packages_autoroller_test.dart
+323
-3
No files found.
dev/bots/analyze.dart
View file @
aac5e95a
...
@@ -1778,7 +1778,7 @@ const Set<String> kExecutableAllowlist = <String>{
...
@@ -1778,7 +1778,7 @@ const Set<String> kExecutableAllowlist = <String>{
'dev/bots/docs.sh'
,
'dev/bots/docs.sh'
,
'dev/conductor/bin/conductor'
,
'dev/conductor/bin/conductor'
,
'dev/conductor/bin/
roll-packages
'
,
'dev/conductor/bin/
packages_autoroller
'
,
'dev/conductor/core/lib/src/proto/compile_proto.sh'
,
'dev/conductor/core/lib/src/proto/compile_proto.sh'
,
'dev/customer_testing/ci.sh'
,
'dev/customer_testing/ci.sh'
,
...
...
dev/conductor/bin/
roll-packages
→
dev/conductor/bin/
packages_autoroller
View file @
aac5e95a
...
@@ -43,4 +43,4 @@ DART_BIN="$REPO_DIR/bin/dart"
...
@@ -43,4 +43,4 @@ DART_BIN="$REPO_DIR/bin/dart"
# Ensure pub get has been run in the repo before running the conductor
# Ensure pub get has been run in the repo before running the conductor
(
cd
"
$REPO_DIR
/dev/conductor/core"
;
"
$DART_BIN
"
pub get 1>&2
)
(
cd
"
$REPO_DIR
/dev/conductor/core"
;
"
$DART_BIN
"
pub get 1>&2
)
exec
"
$DART_BIN
"
--enable-asserts
"
$REPO_DIR
/dev/conductor/core/bin/
roll_packages
.dart"
"
$@
"
exec
"
$DART_BIN
"
--enable-asserts
"
$REPO_DIR
/dev/conductor/core/bin/
packages_autoroller
.dart"
"
$@
"
dev/conductor/core/bin/packages_autoroller.dart
View file @
aac5e95a
...
@@ -9,6 +9,7 @@ import 'package:conductor_core/conductor_core.dart';
...
@@ -9,6 +9,7 @@ import 'package:conductor_core/conductor_core.dart';
import
'package:conductor_core/packages_autoroller.dart'
;
import
'package:conductor_core/packages_autoroller.dart'
;
import
'package:file/file.dart'
;
import
'package:file/file.dart'
;
import
'package:file/local.dart'
;
import
'package:file/local.dart'
;
import
'package:meta/meta.dart'
show
visibleForTesting
;
import
'package:platform/platform.dart'
;
import
'package:platform/platform.dart'
;
import
'package:process/process.dart'
;
import
'package:process/process.dart'
;
...
@@ -17,12 +18,21 @@ const String kGithubClient = 'github-client';
...
@@ -17,12 +18,21 @@ const String kGithubClient = 'github-client';
const
String
kMirrorRemote
=
'mirror-remote'
;
const
String
kMirrorRemote
=
'mirror-remote'
;
const
String
kUpstreamRemote
=
'upstream-remote'
;
const
String
kUpstreamRemote
=
'upstream-remote'
;
Future
<
void
>
main
(
List
<
String
>
args
)
async
{
Future
<
void
>
main
(
List
<
String
>
args
)
{
return
run
(
args
);
}
@visibleForTesting
Future
<
void
>
run
(
List
<
String
>
args
,
{
FileSystem
fs
=
const
LocalFileSystem
(),
ProcessManager
processManager
=
const
LocalProcessManager
(),
})
async
{
final
ArgParser
parser
=
ArgParser
();
final
ArgParser
parser
=
ArgParser
();
parser
.
addOption
(
parser
.
addOption
(
kTokenOption
,
kTokenOption
,
help:
'
GitHub access token env variable nam
e.'
,
help:
'
Path to GitHub access token fil
e.'
,
defaultsTo:
'GITHUB_TOKEN'
,
mandatory:
true
,
);
);
parser
.
addOption
(
parser
.
addOption
(
kGithubClient
,
kGithubClient
,
...
@@ -56,12 +66,17 @@ ${parser.usage}
...
@@ -56,12 +66,17 @@ ${parser.usage}
final
String
mirrorUrl
=
results
[
kMirrorRemote
]!
as
String
;
final
String
mirrorUrl
=
results
[
kMirrorRemote
]!
as
String
;
final
String
upstreamUrl
=
results
[
kUpstreamRemote
]!
as
String
;
final
String
upstreamUrl
=
results
[
kUpstreamRemote
]!
as
String
;
const
Platform
platform
=
LocalPlatform
();
final
String
tokenPath
=
results
[
kTokenOption
]!
as
String
;
final
String
tokenName
=
results
[
kTokenOption
]!
as
String
;
final
File
tokenFile
=
fs
.
file
(
tokenPath
);
final
String
?
token
=
platform
.
environment
[
tokenName
];
if
(!
tokenFile
.
existsSync
())
{
if
(
token
==
null
||
token
.
isEmpty
)
{
throw
ArgumentError
(
throw
FormatException
(
'Provided token path
$tokenPath
but no file exists at
${tokenFile.absolute.path}
'
,
'Tried to read a GitHub access token from env variable
\$
$tokenName
but it was undefined or empty'
,
);
}
final
String
token
=
tokenFile
.
readAsStringSync
().
trim
();
if
(
token
.
isEmpty
)
{
throw
ArgumentError
(
'Tried to read a GitHub access token from file
${tokenFile.path}
but it was empty'
,
);
);
}
}
...
@@ -76,7 +91,7 @@ ${parser.usage}
...
@@ -76,7 +91,7 @@ ${parser.usage}
githubClient:
results
[
kGithubClient
]
as
String
?
??
'gh'
,
githubClient:
results
[
kGithubClient
]
as
String
?
??
'gh'
,
orgName:
_parseOrgName
(
mirrorUrl
),
orgName:
_parseOrgName
(
mirrorUrl
),
token:
token
,
token:
token
,
processManager:
const
LocalProcessManager
()
,
processManager:
processManager
,
).
roll
();
).
roll
();
}
}
...
@@ -126,3 +141,8 @@ Directory get _localFlutterRoot {
...
@@ -126,3 +141,8 @@ Directory get _localFlutterRoot {
);
);
return
fileSystem
.
directory
(
checkoutsDirname
);
return
fileSystem
.
directory
(
checkoutsDirname
);
}
}
@visibleForTesting
void
validateTokenFile
(
String
filePath
,
[
FileSystem
fs
=
const
LocalFileSystem
()])
{
}
dev/conductor/core/lib/src/packages_autoroller.dart
View file @
aac5e95a
...
@@ -10,6 +10,7 @@ import 'package:process/process.dart';
...
@@ -10,6 +10,7 @@ import 'package:process/process.dart';
import
'git.dart'
;
import
'git.dart'
;
import
'globals.dart'
;
import
'globals.dart'
;
import
'repository.dart'
;
import
'repository.dart'
;
import
'stdio.dart'
;
/// A service for rolling the SDK's pub packages to latest and open a PR upstream.
/// A service for rolling the SDK's pub packages to latest and open a PR upstream.
class
PackageAutoroller
{
class
PackageAutoroller
{
...
@@ -19,7 +20,10 @@ class PackageAutoroller {
...
@@ -19,7 +20,10 @@ class PackageAutoroller {
required
this
.
framework
,
required
this
.
framework
,
required
this
.
orgName
,
required
this
.
orgName
,
required
this
.
processManager
,
required
this
.
processManager
,
this
.
githubUsername
=
'fluttergithubbot'
,
Stdio
?
stdio
,
})
{
})
{
this
.
stdio
=
stdio
??
VerboseStdio
.
local
();
if
(
token
.
trim
().
isEmpty
)
{
if
(
token
.
trim
().
isEmpty
)
{
throw
Exception
(
'empty token!'
);
throw
Exception
(
'empty token!'
);
}
}
...
@@ -31,12 +35,16 @@ class PackageAutoroller {
...
@@ -31,12 +35,16 @@ class PackageAutoroller {
}
}
}
}
late
final
Stdio
stdio
;
final
FrameworkRepository
framework
;
final
FrameworkRepository
framework
;
final
ProcessManager
processManager
;
final
ProcessManager
processManager
;
/// Path to GitHub CLI client.
/// Path to GitHub CLI client.
final
String
githubClient
;
final
String
githubClient
;
final
String
githubUsername
;
/// GitHub API access token.
/// GitHub API access token.
final
String
token
;
final
String
token
;
...
@@ -63,23 +71,46 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -63,23 +71,46 @@ This PR was generated by `flutter update-packages --force-upgrade`.
return
name
(
x
);
return
name
(
x
);
})();
})();
void
log
(
String
message
)
{
stdio
.
printStatus
(
_redactToken
(
message
));
}
/// Name of the GitHub organization to push the feature branch to.
/// Name of the GitHub organization to push the feature branch to.
final
String
orgName
;
final
String
orgName
;
Future
<
void
>
roll
()
async
{
Future
<
void
>
roll
()
async
{
await
authLogin
();
try
{
await
updatePackages
();
await
authLogin
();
await
pushBranch
();
final
bool
openPrAlready
=
await
hasOpenPrs
();
await
createPr
(
if
(
openPrAlready
)
{
repository:
await
framework
.
checkoutDirectory
,
// Don't open multiple roll PRs.
);
return
;
await
authLogout
();
}
final
bool
didUpdate
=
await
updatePackages
();
if
(!
didUpdate
)
{
log
(
'Packages are already at latest.'
);
return
;
}
await
pushBranch
();
await
createPr
(
repository:
await
framework
.
checkoutDirectory
);
await
authLogout
();
}
on
Exception
catch
(
exception
)
{
final
String
message
=
_redactToken
(
exception
.
toString
());
throw
Exception
(
'
${exception.runtimeType}
:
$message
'
);
}
}
}
Future
<
void
>
updatePackages
({
// Ensure we don't leak the GitHub token in exception messages
String
_redactToken
(
String
message
)
=>
message
.
replaceAll
(
token
,
'[GitHub TOKEN]'
);
/// Attempt to update all pub packages.
///
/// Will return whether or not any changes were made.
Future
<
bool
>
updatePackages
({
bool
verbose
=
true
,
bool
verbose
=
true
,
String
author
=
'flutter-packages-autoroller <flutter-packages-autoroller@google.com>'
})
async
{
})
async
{
final
String
author
=
'
$githubUsername
<
$githubUsername
@gmail.com>'
;
await
framework
.
newBranch
(
await
featureBranchName
);
await
framework
.
newBranch
(
await
featureBranchName
);
final
io
.
Process
flutterProcess
=
await
framework
.
streamFlutter
(<
String
>[
final
io
.
Process
flutterProcess
=
await
framework
.
streamFlutter
(<
String
>[
if
(
verbose
)
'--verbose'
,
if
(
verbose
)
'--verbose'
,
...
@@ -90,18 +121,26 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -90,18 +121,26 @@ This PR was generated by `flutter update-packages --force-upgrade`.
if
(
exitCode
!=
0
)
{
if
(
exitCode
!=
0
)
{
throw
ConductorException
(
'Failed to update packages with exit code
$exitCode
'
);
throw
ConductorException
(
'Failed to update packages with exit code
$exitCode
'
);
}
}
// If the git checkout is clean, then pub packages are already at latest that cleanly resolve.
if
(
await
framework
.
gitCheckoutClean
())
{
return
false
;
}
await
framework
.
commit
(
await
framework
.
commit
(
'roll packages'
,
'roll packages'
,
addFirst:
true
,
addFirst:
true
,
author:
author
,
author:
author
,
);
);
return
true
;
}
}
Future
<
void
>
pushBranch
()
async
{
Future
<
void
>
pushBranch
()
async
{
final
String
projectName
=
framework
.
mirrorRemote
!.
url
.
split
(
r'/'
).
last
;
// Encode the token into the remote URL for authentication to work
final
String
remote
=
'https://
$token
@
$hostname
/
$orgName
/
$projectName
'
;
await
framework
.
pushRef
(
await
framework
.
pushRef
(
fromRef:
await
featureBranchName
,
fromRef:
await
featureBranchName
,
toRef:
await
featureBranchName
,
toRef:
await
featureBranchName
,
remote:
framework
.
mirrorRemote
!.
url
,
remote:
remote
,
);
);
}
}
...
@@ -123,7 +162,7 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -123,7 +162,7 @@ This PR was generated by `flutter update-packages --force-upgrade`.
'https'
,
'https'
,
'--with-token'
,
'--with-token'
,
],
],
stdin:
token
,
stdin:
'
$token
\n
'
,
);
);
}
}
...
@@ -151,6 +190,8 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -151,6 +190,8 @@ This PR was generated by `flutter update-packages --force-upgrade`.
'
$orgName
:
${await featureBranchName}
'
,
'
$orgName
:
${await featureBranchName}
'
,
'--base'
,
'--base'
,
base
,
base
,
'--label'
,
'tool'
,
if
(
draft
)
if
(
draft
)
'--draft'
,
'--draft'
,
],
],
...
@@ -165,13 +206,16 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -165,13 +206,16 @@ This PR was generated by `flutter update-packages --force-upgrade`.
]);
]);
}
}
Future
<
void
>
cli
(
/// Run a sub-process with the GitHub CLI client.
///
/// Will return STDOUT of the sub-process.
Future
<
String
>
cli
(
List
<
String
>
args
,
{
List
<
String
>
args
,
{
bool
allowFailure
=
false
,
bool
allowFailure
=
false
,
String
?
stdin
,
String
?
stdin
,
String
?
workingDirectory
,
String
?
workingDirectory
,
})
async
{
})
async
{
print
(
'Executing "
$githubClient
${args.join(' ')}
" in
$workingDirectory
'
);
log
(
'Executing "
$githubClient
${args.join(' ')}
" in
$workingDirectory
'
);
final
io
.
Process
process
=
await
processManager
.
start
(
final
io
.
Process
process
=
await
processManager
.
start
(
<
String
>[
githubClient
,
...
args
],
<
String
>[
githubClient
,
...
args
],
workingDirectory:
workingDirectory
,
workingDirectory:
workingDirectory
,
...
@@ -203,6 +247,36 @@ This PR was generated by `flutter update-packages --force-upgrade`.
...
@@ -203,6 +247,36 @@ This PR was generated by `flutter update-packages --force-upgrade`.
args
,
args
,
);
);
}
}
print
(
stdout
);
log
(
stdout
);
return
stdout
;
}
Future
<
bool
>
hasOpenPrs
()
async
{
// gh pr list --author christopherfujino --repo flutter/flutter --state open --json number
final
String
openPrString
=
await
cli
(<
String
>[
'pr'
,
'list'
,
'--author'
,
githubUsername
,
'--repo'
,
'flutter/flutter'
,
'--state'
,
'open'
,
// We are only interested in pub rolls, not devicelab flaky PRs
'--label'
,
'tool'
,
// Return structured JSON with the PR numbers of open PRs
'--json'
,
'number'
,
]);
// This will be an array of objects, one for each open PR.
final
List
<
Object
?>
openPrs
=
json
.
decode
(
openPrString
)
as
List
<
Object
?>;
if
(
openPrs
.
isNotEmpty
)
{
log
(
'
$githubUsername
already has open tool PRs:
\n
$openPrs
'
);
return
true
;
}
return
false
;
}
}
}
}
dev/conductor/core/test/packages_autoroller_test.dart
View file @
aac5e95a
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment