-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
publish
command, auto-publish on post-submit. (#14)
- Loading branch information
1 parent
15de63b
commit 43c856f
Showing
16 changed files
with
359 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,13 @@ jobs: | |
flags: iota | ||
file: packages/iota/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/iota | ||
- run: ./dev.sh publish --packages packages/iota |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,13 @@ jobs: | |
flags: jsonut | ||
file: packages/jsonut/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/jsonut | ||
- run: ./dev.sh publish --packages packages/jsonut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,13 @@ jobs: | |
flags: lore | ||
file: packages/lore/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/lore | ||
- run: ./dev.sh publish --packages packages/lore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,13 @@ jobs: | |
flags: mansion | ||
file: packages/mansion/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/mansion | ||
- run: ./dev.sh publish --packages packages/mansion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,13 @@ jobs: | |
flags: oath | ||
file: packages/oath/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/oath | ||
- run: ./dev.sh publish --packages packages/oath |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,13 @@ jobs: | |
flags: proc | ||
file: packages/proc/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/proc | ||
- run: ./dev.sh publish --packages packages/proc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,13 @@ jobs: | |
flags: webby | ||
file: packages/webby/coverage/lcov.info | ||
fail_ci_if_error: true | ||
publish: | ||
if: github.event_name == 'push' | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/[email protected] | ||
- uses: dart-lang/[email protected] | ||
- run: dart pub get | ||
working-directory: packages/webby | ||
- run: ./dev.sh publish --packages packages/webby |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ import 'package:strink/strink.dart'; | |
/// Generates a GitHub Actions workflow file for a package. | ||
String generateGithubPackageWorkflow({ | ||
required String package, | ||
required bool publishable, | ||
required bool usesChrome, | ||
required bool uploadCoverage, | ||
}) { | ||
|
@@ -63,5 +64,24 @@ String generateGithubPackageWorkflow({ | |
writer.endObjectOrList(); | ||
} | ||
|
||
writer.endObjectOrList(); | ||
writer.endObjectOrList(); | ||
|
||
if (publishable) { | ||
// Add a post-submit job for publishing. | ||
writer.startObjectOrList('publish'); | ||
writer.writeKeyValue('if', "github.event_name == 'push'"); | ||
writer.writeKeyValue('needs', 'build'); | ||
writer.writeKeyValue('runs-on', 'ubuntu-latest'); | ||
writer.startObjectOrList('steps'); | ||
writer.writeListValue('uses: actions/[email protected]'); | ||
writer.writeListValue('uses: dart-lang/[email protected]'); | ||
writer.writeListObject('run', 'dart pub get'); | ||
writer.writeKeyValue('working-directory', 'packages/$package'); | ||
writer.endObjectOrList(); | ||
|
||
writer.writeListValue('run: ./dev.sh publish --packages packages/$package'); | ||
} | ||
|
||
return buffer.toString(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import 'dart:io' as io; | ||
|
||
import 'package:chore/chore.dart'; | ||
import 'package:chore/src/internal/pub_service.dart'; | ||
import 'package:proc/proc.dart'; | ||
|
||
/// A command that publishes a package. | ||
final class Publish extends BaseCommand { | ||
/// Creates a new publish command. | ||
Publish( | ||
super.context, | ||
super.environment, { | ||
PubService? pubService, | ||
}) : _pubService = pubService ?? PubService() { | ||
argParser.addFlag( | ||
'skip-if-already-published', | ||
defaultsTo: environment.isCI, | ||
help: 'Skip publishing if the current version is already published.', | ||
); | ||
argParser.addFlag( | ||
'confirm', | ||
defaultsTo: !environment.isCI, | ||
help: 'Confirm before publishing, even if there are no issues.', | ||
); | ||
} | ||
|
||
@override | ||
String get name => 'publish'; | ||
|
||
@override | ||
String get description => 'Publishes packages.\n' | ||
'\n' | ||
'If no --packages are provided, all publishable packages are attempted.\n' | ||
'\n' | ||
'Locally, this uses stored pub credentials, and on CI, it uses the ' | ||
'PUB_CREDENTIALS environment variable to authenticate.'; | ||
|
||
/// Service to check the status of the package. | ||
final PubService _pubService; | ||
|
||
/// Whether to confirm before publishing. | ||
bool get _confirm => argResults!.flag('confirm'); | ||
|
||
/// Whether to skip publishing if the current version is already published. | ||
bool get _skipIfAlreadyPublished { | ||
return argResults!.flag('skip-if-already-published'); | ||
} | ||
|
||
@override | ||
Future<void> run() async { | ||
Iterable<Package> packages = await context.resolve(globalResults!); | ||
if (!globalResults!.wasParsed('packages')) { | ||
// Skip packages that are not publishable. | ||
packages = packages.where((package) => package.isPublishable); | ||
} | ||
for (final package in packages) { | ||
await _runForPackage(package); | ||
} | ||
} | ||
|
||
Future<void> _runForPackage(Package package) async { | ||
final dartBin = environment.getDartSdk()?.dart; | ||
if (dartBin == null) { | ||
throw StateError('Unable to find dart executable.'); | ||
} | ||
|
||
// The package must be publishable and have a version. | ||
if (!package.isPublishable) { | ||
io.exitCode = 1; | ||
io.stderr.writeln('❌ ${package.name} is not publishable.'); | ||
return; | ||
} | ||
if (package.version == null) { | ||
io.exitCode = 1; | ||
io.stderr.writeln('❌ ${package.name} has no version.'); | ||
return; | ||
} | ||
|
||
// Check if the package is already published as the current version. | ||
if (_skipIfAlreadyPublished) { | ||
final publishedVersion = await _pubService.fetchLatestVersion( | ||
package.name, | ||
); | ||
if (publishedVersion == package.version) { | ||
io.stderr.writeln( | ||
'❕ ${package.name} is already published as ${package.version}.', | ||
); | ||
return; | ||
} | ||
} | ||
|
||
// Run dart publish. | ||
io.stderr.writeln('Publishing ${package.name}...'); | ||
{ | ||
final process = await environment.processHost.start( | ||
dartBin.binPath, | ||
[ | ||
'pub', | ||
'lish', | ||
if (!_confirm) '--force', | ||
], | ||
runMode: ProcessRunMode.inheritStdio, | ||
workingDirectory: package.path, | ||
); | ||
if ((await process.exitCode).isFailure) { | ||
io.exitCode = 1; | ||
io.stderr.writeln('❌ Publishing failed.'); | ||
} else { | ||
io.stderr.writeln('✅ Publishing succeeded.'); | ||
} | ||
io.stderr.writeln(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Adapted from <https://github.com/flutter/packages/blob/3515abab07d0bb2441277f43c2411c9b5e4ecf94/script/tool/lib/src/common/pub_version_finder.dart>. | ||
|
||
import 'dart:io' as io; | ||
import 'dart:typed_data'; | ||
|
||
import 'package:jsonut/jsonut.dart'; | ||
|
||
/// Interfaces with a pub host, such as `pub.dev`. | ||
final class PubService { | ||
/// Creates a new pub service. | ||
/// | ||
/// The [pubHost] defaults to `https://pub.dev` if not provided. | ||
/// | ||
/// The [httpGet] function defaults to using `dart:io` if not provided. | ||
PubService({ | ||
Uri? pubHost, | ||
Future<HttpResponse> Function(Uri)? httpGet, | ||
}) : _pubHost = pubHost ?? _defaultHost, | ||
_httpGet = httpGet ?? _defaultHttpGet; | ||
final Uri _pubHost; | ||
static final _defaultHost = Uri(scheme: 'https', host: 'pub.dev'); | ||
|
||
final Future<HttpResponse> Function(Uri) _httpGet; | ||
static Future<HttpResponse> _defaultHttpGet(Uri uri) async { | ||
final client = io.HttpClient(); | ||
try { | ||
final request = await client.getUrl(uri); | ||
final response = await request.close(); | ||
final builder = BytesBuilder(copy: false); | ||
await response.forEach(builder.add); | ||
return HttpResponse( | ||
statusCode: response.statusCode, | ||
body: builder.takeBytes(), | ||
); | ||
} finally { | ||
client.close(); | ||
} | ||
} | ||
|
||
/// Fetches the latest version of a package from the pub host. | ||
Future<String> fetchLatestVersion(String package) async { | ||
final uri = _pubHost.replace(path: '/packages/$package.json'); | ||
final response = await _httpGet(uri); | ||
return switch (response.statusCode) { | ||
404 => throw ArgumentError('Package not found: $package'), | ||
200 => response.decodeAsJson()['versions'].array().first.string(), | ||
_ => throw StateError('Error fetching $package: ${response.statusCode}'), | ||
}; | ||
} | ||
} | ||
|
||
/// A minimal HTTP response. | ||
final class HttpResponse { | ||
/// Creates a new HTTP response. | ||
const HttpResponse({ | ||
required this.statusCode, | ||
required this.body, | ||
}); | ||
|
||
/// The status code of the response. | ||
final int statusCode; | ||
|
||
/// The response body. | ||
final Uint8List body; | ||
|
||
/// Decodes the body as a JSON object. | ||
JsonObject decodeAsJson() => JsonObject.parseUtf8(body); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.