Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions .github/workflows/release_from_branches.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Batch Release
on:
push:
branches:
- 'release-go_router'
jobs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to reuse a common release sub workflow for both release from branches and release from main in the future, we should refactor it now for release from branches.

because we have to make sure the sub workflow works before using it for release from main, so we might as well do it now for release from branches.

release:
uses: ./.github/workflows/resuable_release.yml
with:
is-batch-release: true
branch-name: '${{ github.ref_name }}'
secrets: inherit
84 changes: 84 additions & 0 deletions .github/workflows/reusable_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Reusable Release
on:
workflow_call:
inputs:
is-batch-release:
required: true
type: boolean
branch-name:
required: true
type: string
# Declare default permissions as read only.
permissions: read-all
jobs:
release:
if: github.repository_owner == 'flutter'
name: release
permissions:
# Release needs to push a tag back to the repo.
contents: write
runs-on: ubuntu-latest
steps:
# Checks out a copy of the repo.
- name: Check out code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
with:
fetch-depth: 0 # Fetch all history so the tool can get all the tags to determine version.
ref: ${{ inputs.branch-name }}
- name: "Install Flutter"
uses: ./.github/workflows/internals/install_flutter
- name: Set up tools
run: dart pub get
working-directory: ${{ github.workspace }}/script/tool

# Give some time for LUCI checks to start becoming populated.
# Because of latency in Github Webhooks, we need to wait for a while
# before being able to look at checks scheduled by LUCI.
- name: Give webhooks a minute
run: sleep 60s
shell: bash

# The next step waits for all tests, but when there are issues with the
# hooks it can take a long time for the tests to even be registered. If
# "Wait on all tests" runs before that happens, it will pass immediately
# because there doesn't appear to be anything to wait for. To avoid that,
# explicitly wait for one LUCI test by name first.
- name: Wait for test check-in
uses: lewagon/wait-on-check-action@0dceb95e7c4cad8cc7422aee3885998f5cab9c79
with:
ref: ${{ github.sha }}
check-name: 'Linux ci_yaml packages roller'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 30 # seconds
allowed-conclusions: success,neutral
# verbose:true will produce too many logs that hang github actions web UI.
verbose: false

# This workflow should be the last to run. So wait for all the other tests to succeed.
- name: Wait on all tests
uses: lewagon/wait-on-check-action@0dceb95e7c4cad8cc7422aee3885998f5cab9c79
with:
ref: ${{ github.sha }}
running-workflow-name: 'release'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 180 # seconds
allowed-conclusions: success,neutral
# verbose:true will produce too many logs that hang github actions web UI.
verbose: false

- name: run release
run: |
git config --global user.name "${{ secrets.USER_NAME }}"
git config --global user.email "${{ secrets.USER_EMAIL }}"

# Build the flag string based on the input
BATCH_FLAG=""
if [ "${{ inputs.is-batch-release }}" = "true" ]; then
BATCH_FLAG="--batch-release-branch=${{ inputs.branch-name }}"
fi
dart ./script/tool/lib/src/main.dart publish \
--all-changed \
$BATCH_FLAG \
--base-sha=HEAD~ \
--skip-confirmation
env: {PUB_CREDENTIALS: "${{ secrets.PUB_CREDENTIALS }}"}
42 changes: 42 additions & 0 deletions script/tool/lib/src/publish_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class PublishCommand extends PackageLoopingCommand {
'Release all packages that contains pubspec changes at the current commit compares to the base-sha.\n'
'The --packages option is ignored if this is on.',
);
argParser.addOption(
_batchReleaseBranchOption,
help: 'batch release a package from its release branch',
);
argParser.addFlag(
_dryRunFlag,
help:
Expand All @@ -109,6 +113,7 @@ class PublishCommand extends PackageLoopingCommand {
static const String _pubFlagsOption = 'pub-publish-flags';
static const String _remoteOption = 'remote';
static const String _allChangedFlag = 'all-changed';
static const String _batchReleaseBranchOption = 'batch-release-branch';
static const String _dryRunFlag = 'dry-run';
static const String _skipConfirmationFlag = 'skip-confirmation';
static const String _tagForAutoPublishFlag = 'tag-for-auto-publish';
Expand Down Expand Up @@ -186,6 +191,9 @@ class PublishCommand extends PackageLoopingCommand {

@override
Stream<PackageEnumerationEntry> getPackagesToProcess() async* {
final String batchReleaseBranchName = getStringArg(
_batchReleaseBranchOption,
);
if (getBoolArg(_allChangedFlag)) {
print(
'Publishing all packages that have changed relative to "$baseSha"\n',
Expand All @@ -196,6 +204,40 @@ class PublishCommand extends PackageLoopingCommand {
.toList();

for (final pubspecPath in changedPubspecs) {
// Read the ci_config.yaml file if it exists
final String packageName = p.basename(p.dirname(pubspecPath));
final bool isBatchReleasePackage;
try {
final File ciConfigFile = RepositoryPackage(
packagesDir.fileSystem.file(pubspecPath).parent,
).ciConfigFile;

if (!ciConfigFile.existsSync()) {
isBatchReleasePackage = false;
} else {
final ciConfig = CIConfig.parse(ciConfigFile.readAsStringSync());
isBatchReleasePackage = ciConfig.isBatchRelease;
}
} catch (e) {
printError('Could not parse ci_config.yaml for $packageName: $e');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should throw tool exit in this case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also should add a test for this

throw ToolExit(exitCommandFoundErrors);
}

// When releasing from the main branch, skip the batch release packages.
if (batchReleaseBranchName.isEmpty) {
if (isBatchReleasePackage) {
continue;
}
} else {
// When releasing from a batch release branch, verify the package has
// the opt-in flag and that the package name matches the branch suffix.
// Example: branch "release-go_router" matches package "go_router".
if (!isBatchReleasePackage ||
batchReleaseBranchName != 'release-$packageName') {
continue;
}
}

// git outputs a relativa, Posix-style path.
final File pubspecFile = childFileWithSubcomponents(
packagesDir.fileSystem.directory((await gitDir).path),
Expand Down
Loading
Loading