-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. --> <!-- You can skip the changelog check by labeling the PR with "no changelog". --> # Why We want to allow users to start workflows manually. # How I added a `createRunMutation` to GraphQL and used it here. We upload project archive, `eas.json` and use to start a new workflow run. # Test Plan ``` Workflows are in beta and subject to breaking changes. Compressing project files and uploading to EAS. Learn more: https://expo.fyi/eas-build-archive ✔ Uploaded eas.json to EAS ✔ Uploaded project archive to EAS 1s ✔ Workflow started successfully. https://staging.expo.dev/accounts/sjchmiela/projects/staging-app/workflows/019301f1-b1b4-700d-9e3b-82dc97d76a32 ``` Co-authored-by: Szymon Dziedzic <[email protected]>
- Loading branch information
1 parent
d47b80a
commit b81c60e
Showing
10 changed files
with
2,834 additions
and
247 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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 |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import fs from 'node:fs'; | ||
import * as path from 'node:path'; | ||
|
||
import { getWorkflowRunUrl } from '../../build/utils/url'; | ||
import EasCommand from '../../commandUtils/EasCommand'; | ||
import { EASNonInteractiveFlag } from '../../commandUtils/flags'; | ||
import { WorkflowProjectSourceType } from '../../graphql/generated'; | ||
import { WorkflowRunMutation } from '../../graphql/mutations/WorkflowRunMutation'; | ||
import Log, { link } from '../../log'; | ||
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils'; | ||
import { uploadAccountScopedEasJsonAsync } from '../../project/uploadAccountScopedEasJsonAsync'; | ||
import { uploadAccountScopedProjectSourceAsync } from '../../project/uploadAccountScopedProjectSourceAsync'; | ||
|
||
export default class WorkflowRun extends EasCommand { | ||
static override description = 'Run an EAS workflow'; | ||
|
||
// TODO(@sjchmiela): Keep command hidden until workflows are live | ||
static override hidden = true; | ||
static override state = 'beta'; | ||
|
||
static override args = [{ name: 'file', description: 'Path to the workflow file to run' }]; | ||
|
||
static override flags = { | ||
...EASNonInteractiveFlag, | ||
}; | ||
|
||
static override contextDefinition = { | ||
...this.ContextOptions.DynamicProjectConfig, | ||
...this.ContextOptions.ProjectDir, | ||
...this.ContextOptions.Vcs, | ||
...this.ContextOptions.LoggedIn, | ||
}; | ||
|
||
async runAsync(): Promise<void> { | ||
const { flags, args } = await this.parse(WorkflowRun); | ||
|
||
Log.warn('Workflows are in beta and subject to breaking changes.'); | ||
|
||
const { | ||
getDynamicPrivateProjectConfigAsync, | ||
loggedIn: { graphqlClient }, | ||
vcsClient, | ||
projectDir, | ||
} = await this.getContextAsync(WorkflowRun, { | ||
nonInteractive: flags['non-interactive'], | ||
withServerSideEnvironment: null, | ||
}); | ||
|
||
let yamlConfig: string; | ||
try { | ||
yamlConfig = await fs.promises.readFile(path.join(projectDir, args.file), 'utf8'); | ||
} catch (err) { | ||
Log.error('Failed to read workflow file.'); | ||
|
||
throw err; | ||
} | ||
|
||
const { | ||
projectId, | ||
exp: { slug: projectName }, | ||
} = await getDynamicPrivateProjectConfigAsync(); | ||
const account = await getOwnerAccountForProjectIdAsync(graphqlClient, projectId); | ||
|
||
let projectArchiveBucketKey: string; | ||
let easJsonBucketKey: string; | ||
|
||
try { | ||
({ projectArchiveBucketKey } = await uploadAccountScopedProjectSourceAsync({ | ||
graphqlClient, | ||
vcsClient, | ||
accountId: account.id, | ||
})); | ||
({ easJsonBucketKey } = await uploadAccountScopedEasJsonAsync({ | ||
graphqlClient, | ||
accountId: account.id, | ||
projectDir, | ||
})); | ||
} catch (err) { | ||
Log.error('Failed to upload project sources.'); | ||
|
||
throw err; | ||
} | ||
|
||
try { | ||
const { id: workflowRunId } = await WorkflowRunMutation.createWorkflowRunAsync( | ||
graphqlClient, | ||
{ | ||
appId: projectId, | ||
workflowRevisionInput: { | ||
fileName: path.basename(args.file), | ||
yamlConfig, | ||
}, | ||
workflowRunInput: { | ||
projectSource: { | ||
type: WorkflowProjectSourceType.Gcs, | ||
projectArchiveBucketKey, | ||
easJsonBucketKey, | ||
}, | ||
}, | ||
} | ||
); | ||
|
||
Log.newLine(); | ||
Log.succeed( | ||
`Workflow started successfully. ${link( | ||
getWorkflowRunUrl(account.name, projectName, workflowRunId) | ||
)}` | ||
); | ||
} catch (err) { | ||
Log.error('Failed to start the workflow with the API.'); | ||
|
||
throw err; | ||
} | ||
} | ||
} |
Oops, something went wrong.