Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow GitHub workflow_dispatch events to publish #7462

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Important changes to data models, configuration, and migrations between each
AppEngine version, listed here to ease deployment and troubleshooting.

## Next Release (replace with git tag when deployed)
* Allowed `workflow_dispatch` events from GitHub Actions to publish.
* Bumped runtimeVersion to `2024.05.28`.
* Upgraded stable Dart analysis SDK to `3.4.1`
* Upgraded stable Flutter analysis SDK to `3.22.1`.
Expand Down Expand Up @@ -65,7 +66,6 @@ AppEngine version, listed here to ease deployment and troubleshooting.
* Resyncing all `SecurityAdvisory` entities to get `pub_display_url` in the
`database_specific` field backfilled.


## `20240227t140000-all`
* Bumped runtimeVersion to `2024.02.27`.
* Upgraded pana to `0.22.2`.
Expand Down
6 changes: 4 additions & 2 deletions app/lib/package/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1318,9 +1318,11 @@ class PackageBackend {

// TODO: consider allowing other events from
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows
if (agent.payload.eventName != 'push') {
if (agent.payload.eventName != 'push' &&
agent.payload.eventName != 'workflow_dispatch') {
throw AuthorizationException.githubActionIssue(
'publishing is only allowed from "push" events, this token originates from a "${agent.payload.eventName}" event');
'publishing is only allowed from "push" and "workflow_dispatch events, '
'this token originates from a "${agent.payload.eventName}" event');
}

if (agent.payload.refType != 'tag') {
Expand Down
68 changes: 68 additions & 0 deletions app/test/package/upload_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,74 @@ void main() {
expect(rs.success.message, contains('Successfully uploaded'));
});

testWithProfile(
'successful upload with GitHub Actions through workflow_dispatch',
fn: () async {
await withFakeAuthHttpPubApiClient(
email: adminAtPubDevEmail,
fn: (client) async {
await client.setAutomatedPublishing(
'oxygen',
AutomatedPublishingConfig(
github: GithubPublishingConfig(
isEnabled: true,
repository: 'a/b',
tagPattern: '{{version}}',
),
),
);
},
);
final token = createFakeGithubActionToken(
repository: 'a/b',
ref: 'refs/tags/2.2.0',
eventName: 'workflow_dispatch',
);
final pubspecContent = generatePubspecYaml('oxygen', '2.2.0');
final bytes = await packageArchiveBytes(pubspecContent: pubspecContent);
final rs = await createPubApiClient(authToken: token)
.uploadPackageBytes(bytes);
expect(rs.success.message,
'Successfully uploaded https://pub.dev/packages/oxygen version 2.2.0.');
});

testWithProfile(
'GitHub Actions through workflow_dispatch cannot upload without targeting a tag',
fn: () async {
await withFakeAuthHttpPubApiClient(
email: adminAtPubDevEmail,
fn: (client) async {
await client.setAutomatedPublishing(
'oxygen',
AutomatedPublishingConfig(
github: GithubPublishingConfig(
isEnabled: true,
repository: 'a/b',
tagPattern: '{{version}}',
),
),
);
},
);
final token = createFakeGithubActionToken(
repository: 'a/b',
ref: 'refs/heads/main',
eventName: 'workflow_dispatch',
);
final pubspecContent = generatePubspecYaml('oxygen', '2.2.0');
final bytes = await packageArchiveBytes(pubspecContent: pubspecContent);
final rs =
createPubApiClient(authToken: token).uploadPackageBytes(bytes);
await expectApiException(rs,
status: 403,
code: 'InsufficientPermissions',
message:
'The calling GitHub Action is not allowed to publish, because: '
'publishing is only allowed from \"tag\" refType, this token '
'has \"head\" refType.\n'
'See https://dart.dev/go/publishing-from-github');
});

testWithProfile(
'successful upload with GitHub Actions (exempted package)',
testProfile: TestProfile(
Expand Down