Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
wip! Add “up” button
Browse files Browse the repository at this point in the history
  • Loading branch information
jgwhite committed May 25, 2021
1 parent db85e1f commit 2747f9f
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 13 deletions.
13 changes: 13 additions & 0 deletions ui/app/components/up-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<span class="up-button">
{{#if this.currentMessage}}
<code class="up-button__msg">{{this.currentMessage}}</code>
{{/if}}
<Pds::Button
@variant="primary"
@compact={{true}}
disabled={{this.up.isRunning}}
{{on "click" (perform this.up @application)}}
>
waypoint up
</Pds::Button>
</span>
94 changes: 94 additions & 0 deletions ui/app/components/up-button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import ApiService from 'waypoint/services/api';
import PollModelService from 'waypoint/services/poll-model';
import {
Ref,
Job,
QueueJobRequest,
QueueJobResponse,
GetJobRequest,
GetJobStreamResponse,
} from 'waypoint-pb';
import { task } from 'ember-concurrency-decorators';
import { perform } from 'ember-concurrency-ts';
import { tracked } from '@glimmer/tracking';

interface UpButtonArgs {
application: Ref.Application.AsObject;
}

export default class UpButton extends Component<UpButtonArgs> {
@service api!: ApiService;
@service pollModel!: PollModelService;

@tracked currentMessage?: string;

@task
async up(appObject: Ref.Application.AsObject): Promise<void> {
this.currentMessage = undefined;

let job = new Job();
let upOp = new Job.UpOp();
let request = new QueueJobRequest();
let metadata = this.api.WithMeta();
let application = new Ref.Application();
let workspace = new Ref.Workspace();
let runner = new Ref.Runner();

workspace.setWorkspace('default');

application.setApplication(appObject.application);
application.setProject(appObject.project);

runner.setAny(new Ref.RunnerAny());

job.setApplication(application);
job.setUp(upOp);
job.setTargetRunner(runner);
job.setWorkspace(workspace);

request.setJob(job);

let response: QueueJobResponse = await this.api.client.queueJob(request, metadata);

await perform(this.streamJob, response.getJobId());

this.currentMessage = undefined;
this.pollModel.route?.refresh();
}

@task
async streamJob(jobId: string): Promise<void> {
let request = new GetJobRequest();
let metadata = this.api.WithMeta();

request.setJobId(jobId);

let stream = this.api.client.getJobStream(request, metadata);

await new Promise<void>((resolve, reject) => {
stream.on('status', (resp) => console.log(resp));
stream.on('metadata', (resp) => console.log(resp));
stream.on('data', (resp: GetJobStreamResponse) => {
resp
.getTerminal()
?.getEventsList()
.map((event) => event.getLine()?.getMsg())
.filter(notEmpty)
.forEach((msg) => {
this.pollModel.route?.refresh();
this.currentMessage = msg;
});
});
stream.on('error', reject);
stream.on('end', () => {
resolve();
});
});
}
}

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}
1 change: 1 addition & 0 deletions ui/app/routes/workspace/projects/project/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default class App extends Route {
let ObjectPromiseProxy = ObjectProxy.extend(PromiseProxyMixin);

return hash({
project: proj,
application: appRef.toObject(),
deployments: ObjectPromiseProxy.create({
promise: resolve(this.api.listDeployments(wsRef, appRef)),
Expand Down
5 changes: 5 additions & 0 deletions ui/app/styles/_up-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.up-button__msg {
font-size: scale.$sm--1;
margin-right: scale.$sm--2;
color: color.$ui-cool-gray-600;
}
1 change: 1 addition & 0 deletions ui/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ svg.icon {
@import './pds-form';
@import './status-badge';
@import './x-toggle';
@import './up-button';
30 changes: 17 additions & 13 deletions ui/app/templates/workspace/projects/project/app.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,26 @@
</small>
</div>
<div class="actions">
{{#if @model.releases.length}}
<LatestReleaseUrl @releases={{@model.releases}}></LatestReleaseUrl>
{{#if @model.project.remoteEnabled}}
<UpButton @application={{@model.application}} />
{{else}}
<div class="first-run-hint">
{{#if (and @model.builds.length @model.deployments.length)}}
<p>To create your first release from your latest deployment, run:</p>
<CopyableCode @ref="hint-release" @inline="true">
<code id="hint-release">waypoint release</code>
</CopyableCode>
{{#if @model.releases.length}}
<LatestReleaseUrl @releases={{@model.releases}}></LatestReleaseUrl>
{{else}}
<p>To create your first release, run the following to create a build, deployment and release:</p>
<CopyableCode @ref="hint-release" @inline="true">
<code id="hint-release">waypoint up</code>
</CopyableCode>
<div class="first-run-hint">
{{#if (and @model.builds.length @model.deployments.length)}}
<p>To create your first release from your latest deployment, run:</p>
<CopyableCode @ref="hint-release" @inline="true">
<code id="hint-release">waypoint release</code>
</CopyableCode>
{{else}}
<p>To create your first release, run the following to create a build, deployment and release:</p>
<CopyableCode @ref="hint-release" @inline="true">
<code id="hint-release">waypoint up</code>
</CopyableCode>
{{/if}}
</div>
{{/if}}
</div>
{{/if}}
</div>
</PageHeader>
Expand Down
64 changes: 64 additions & 0 deletions ui/tests/acceptance/up-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { module, test, todo } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit, find } from '@ember/test-helpers';
import { setupMirage } from 'ember-cli-mirage/test-support';
import login from 'waypoint/tests/helpers/login';

module('Acceptance | up', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
login();

test('happy path', async function (assert) {
// Given I have a project with remote runners enabled
let workspace = this.server.create('workspace', 'default');
let project = this.server.create('project', 'simple', 'with-remote-runners');
let app = this.server.create('application', 'simple', { project });

// And I am viewing an app in that project
await visit(`/${workspace.name}/${project.name}/app/${app.name}`);

assert.ok(find('main'));
// When I click “build, deploy & release”
// Then I see “Building...”
// And I see a new build appear in the list
// And I see “Deploying...”
// And I see a new deployment appear in the list
// And I see “Releasing...”
// And I see a new release appear in the list
// And I see the button become re-enabled
});

todo('build fails', function (assert) {
// Given I have a project with remote runners enabled
// And I am viewing an app in that project
// When I click “build, deploy & release”
// Then I see “Building...”
// And I see a new build appear in the list with an error
// And I see the button become re-enabled
});

todo('deploy fails', function (assert) {
// Given I have a project with remote runners enabled
// And I am viewing an app in that project
// When I click “build, deploy & release”
// Then I see “Building...”
// And I see a new build appear in the list
// And I see “Deploying...”
// And I see a new deployment appear in the list with an error
// And I see the button become re-enabled
});

todo('release fails', function (assert) {
// Given I have a project with remote runners enabled
// And I am viewing an app in that project
// When I click “build, deploy & release”
// Then I see “Building...”
// And I see a new build appear in the list
// And I see “Deploying...”
// And I see a new deployment appear in the list
// And I see “Releasing...”
// And I see a new release appear in the list with an error
// And I see the button become re-enabled
});
});

0 comments on commit 2747f9f

Please sign in to comment.