Skip to content

Commit e674e0d

Browse files
author
Chris Yang
authored
[tool] add an skip-confirmation flag to publish-package for running the command on ci (flutter#3842)
the skip-confirmation flag will add a --force flag to pub publish, it will also let users to skip the y/n question when pushing tags to remote. Fixes flutter#79830
1 parent 145b6cf commit e674e0d

File tree

3 files changed

+171
-57
lines changed

3 files changed

+171
-57
lines changed

script/tool/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Add `against-pub` flag for version-check, which allows the command to check version with pub.
44
- Add `machine` flag for publish-check, which replaces outputs to something parsable by machines.
5+
- Add `skip-conformation` flag to publish-plugin to allow auto publishing.
56

67
## 0.1.1
78

script/tool/lib/src/publish_plugin_command.dart

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ class PublishPluginCommand extends PluginCommand {
8484
defaultsTo: false,
8585
negatable: true,
8686
);
87+
argParser.addFlag(_skipConfirmationFlag,
88+
help: 'Run the command without asking for Y/N inputs.\n'
89+
'This command will add a `--force` flag to the `pub publish` command if it is not added with $_pubFlagsOption\n'
90+
'It also skips the y/n inputs when pushing tags to remote.\n',
91+
defaultsTo: false,
92+
negatable: true);
8793
}
8894

8995
static const String _packageOption = 'package';
@@ -93,6 +99,9 @@ class PublishPluginCommand extends PluginCommand {
9399
static const String _remoteOption = 'remote';
94100
static const String _allChangedFlag = 'all-changed';
95101
static const String _dryRunFlag = 'dry-run';
102+
static const String _skipConfirmationFlag = 'skip-confirmation';
103+
104+
static const String _pubCredentialName = 'PUB_CREDENTIALS';
96105

97106
// Version tags should follow <package-name>-v<semantic-version>. For example,
98107
// `flutter_plugin_tools-v0.0.24`.
@@ -103,7 +112,9 @@ class PublishPluginCommand extends PluginCommand {
103112

104113
@override
105114
final String description =
106-
'Attempts to publish the given plugin and tag its release on GitHub.';
115+
'Attempts to publish the given plugin and tag its release on GitHub.\n'
116+
'If running this on CI, an environment variable named $_pubCredentialName must be set to a String that represents the pub credential JSON.\n'
117+
'WARNING: Do not check in the content of pub credential JSON, it should only come from secure sources.';
107118

108119
final Print _print;
109120
final io.Stdin _stdin;
@@ -267,7 +278,8 @@ Safe to ignore if the package is deleted in this commit.
267278
}
268279

269280
if (pubspec.version == null) {
270-
_print('No version found. A package that intentionally has no version should be marked "publish_to: none"');
281+
_print(
282+
'No version found. A package that intentionally has no version should be marked "publish_to: none"');
271283
return _CheckNeedsReleaseResult.failure;
272284
}
273285

@@ -408,24 +420,33 @@ Safe to ignore if the package is deleted in this commit.
408420
argResults[_pubFlagsOption] as List<String>;
409421
_print(
410422
'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n');
411-
if (!(argResults[_dryRunFlag] as bool)) {
412-
final io.Process publish = await processRunner.start(
413-
'flutter', <String>['pub', 'publish'] + publishFlags,
414-
workingDirectory: packageDir);
415-
publish.stdout
416-
.transform(utf8.decoder)
417-
.listen((String data) => _print(data));
418-
publish.stderr
419-
.transform(utf8.decoder)
420-
.listen((String data) => _print(data));
421-
_stdinSubscription ??= _stdin
422-
.transform(utf8.decoder)
423-
.listen((String data) => publish.stdin.writeln(data));
424-
final int result = await publish.exitCode;
425-
if (result != 0) {
426-
_print('Publish ${packageDir.basename} failed.');
427-
return false;
428-
}
423+
if (argResults[_dryRunFlag] as bool) {
424+
return true;
425+
}
426+
427+
if (argResults[_skipConfirmationFlag] as bool) {
428+
publishFlags.add('--force');
429+
}
430+
if (publishFlags.contains('--force')) {
431+
_ensureValidPubCredential();
432+
}
433+
434+
final io.Process publish = await processRunner.start(
435+
'flutter', <String>['pub', 'publish'] + publishFlags,
436+
workingDirectory: packageDir);
437+
publish.stdout
438+
.transform(utf8.decoder)
439+
.listen((String data) => _print(data));
440+
publish.stderr
441+
.transform(utf8.decoder)
442+
.listen((String data) => _print(data));
443+
_stdinSubscription ??= _stdin
444+
.transform(utf8.decoder)
445+
.listen((String data) => publish.stdin.writeln(data));
446+
final int result = await publish.exitCode;
447+
if (result != 0) {
448+
_print('Publish ${packageDir.basename} failed.');
449+
return false;
429450
}
430451
return true;
431452
}
@@ -453,11 +474,13 @@ Safe to ignore if the package is deleted in this commit.
453474
@required String remoteUrl,
454475
}) async {
455476
assert(remote != null && tag != null && remoteUrl != null);
456-
_print('Ready to push $tag to $remoteUrl (y/n)?');
457-
final String input = _stdin.readLineSync();
458-
if (input.toLowerCase() != 'y') {
459-
_print('Tag push canceled.');
460-
return false;
477+
if (!(argResults[_skipConfirmationFlag] as bool)) {
478+
_print('Ready to push $tag to $remoteUrl (y/n)?');
479+
final String input = _stdin.readLineSync();
480+
if (input.toLowerCase() != 'y') {
481+
_print('Tag push canceled.');
482+
return false;
483+
}
461484
}
462485
if (!(argResults[_dryRunFlag] as bool)) {
463486
final io.ProcessResult result = await processRunner.run(
@@ -473,8 +496,50 @@ Safe to ignore if the package is deleted in this commit.
473496
}
474497
return true;
475498
}
499+
500+
void _ensureValidPubCredential() {
501+
final File credentialFile = fileSystem.file(_credentialsPath);
502+
if (credentialFile.existsSync() &&
503+
credentialFile.readAsStringSync().isNotEmpty) {
504+
return;
505+
}
506+
final String credential = io.Platform.environment[_pubCredentialName];
507+
if (credential == null) {
508+
printErrorAndExit(errorMessage: '''
509+
No pub credential available. Please check if `~/.pub-cache/credentials.json` is valid.
510+
If running this command on CI, you can set the pub credential content in the $_pubCredentialName environment variable.
511+
''');
512+
}
513+
credentialFile.openSync(mode: FileMode.writeOnlyAppend)
514+
..writeStringSync(credential)
515+
..closeSync();
516+
}
517+
518+
/// Returns the correct path where the pub credential is stored.
519+
@visibleForTesting
520+
static String getCredentialPath() {
521+
return _credentialsPath;
522+
}
476523
}
477524

525+
/// The path in which pub expects to find its credentials file.
526+
final String _credentialsPath = () {
527+
// This follows the same logic as pub:
528+
// https://github.com/dart-lang/pub/blob/d99b0d58f4059d7bb4ac4616fd3d54ec00a2b5d4/lib/src/system_cache.dart#L34-L43
529+
String cacheDir;
530+
final String pubCache = io.Platform.environment['PUB_CACHE'];
531+
print(pubCache);
532+
if (pubCache != null) {
533+
cacheDir = pubCache;
534+
} else if (io.Platform.isWindows) {
535+
final String appData = io.Platform.environment['APPDATA'];
536+
cacheDir = p.join(appData, 'Pub', 'Cache');
537+
} else {
538+
cacheDir = p.join(io.Platform.environment['HOME'], '.pub-cache');
539+
}
540+
return p.join(cacheDir, 'credentials.json');
541+
}();
542+
478543
enum _CheckNeedsReleaseResult {
479544
// The package needs to be released.
480545
release,

0 commit comments

Comments
 (0)