@spinnaker/core 2026.0.3 → 2026.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/ci/igor.service.d.ts +0 -1
  2. package/dist/domain/ITrigger.d.ts +1 -11
  3. package/dist/index.js +36 -36
  4. package/dist/index.js.map +1 -1
  5. package/dist/managed/graphql/client.d.ts +1 -1
  6. package/dist/managed/graphql/graphql-sdk.d.ts +9 -9
  7. package/dist/pipeline/config/stages/bakeManifest/ManifestRenderers.d.ts +2 -2
  8. package/dist/pipeline/config/triggers/Triggers.d.ts +1 -0
  9. package/dist/pipeline/config/triggers/index.d.ts +0 -1
  10. package/package.json +3 -3
  11. package/src/application/search/react-ultimate-pagination.d.ts +1 -1
  12. package/src/ci/igor.service.ts +0 -1
  13. package/src/domain/ITrigger.ts +1 -13
  14. package/src/help/help.contents.ts +1 -9
  15. package/src/pipeline/config/pipelineConfigView.html +1 -0
  16. package/src/pipeline/config/stages/bakeManifest/ManifestRenderers.ts +2 -2
  17. package/src/pipeline/config/stages/createLoadBalancer/createLoadBalancerStage.js +45 -28
  18. package/src/pipeline/config/stages/createLoadBalancer/createLoadBalancerStage.spec.js +101 -0
  19. package/src/pipeline/config/triggers/MetadataPageContent.spec.tsx +140 -0
  20. package/src/pipeline/config/triggers/Triggers.spec.tsx +80 -0
  21. package/src/pipeline/config/triggers/Triggers.tsx +6 -1
  22. package/src/pipeline/config/triggers/index.ts +0 -1
  23. package/src/pipeline/config/triggers/triggers.module.ts +1 -0
  24. package/src/pipeline/pipeline.module.ts +0 -2
  25. package/src/presentation/ReactModal.spec.tsx +72 -0
  26. package/src/presentation/ReactModal.tsx +12 -2
  27. package/dist/pipeline/config/stages/wercker/WerckerExecutionLabel.d.ts +0 -7
  28. package/dist/pipeline/config/stages/wercker/modal/addParameter.controller.modal.d.ts +0 -10
  29. package/dist/pipeline/config/stages/wercker/werckerExecutionDetails.controller.d.ts +0 -18
  30. package/dist/pipeline/config/stages/wercker/werckerStage.d.ts +0 -51
  31. package/dist/pipeline/config/stages/wercker/werckerStage.module.d.ts +0 -1
  32. package/dist/pipeline/config/triggers/wercker/WerckerTrigger.d.ts +0 -13
  33. package/dist/pipeline/config/triggers/wercker/WerckerTriggerTemplate.d.ts +0 -7
  34. package/dist/pipeline/config/triggers/wercker/wercker.trigger.d.ts +0 -1
  35. package/src/pipeline/config/stages/wercker/WerckerExecutionLabel.tsx +0 -32
  36. package/src/pipeline/config/stages/wercker/modal/addParameter.controller.modal.ts +0 -19
  37. package/src/pipeline/config/stages/wercker/modal/addParameter.html +0 -48
  38. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.controller.spec.ts +0 -79
  39. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.controller.ts +0 -55
  40. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.html +0 -79
  41. package/src/pipeline/config/stages/wercker/werckerStage.controller.spec.ts +0 -152
  42. package/src/pipeline/config/stages/wercker/werckerStage.html +0 -150
  43. package/src/pipeline/config/stages/wercker/werckerStage.module.ts +0 -18
  44. package/src/pipeline/config/stages/wercker/werckerStage.ts +0 -232
  45. package/src/pipeline/config/triggers/wercker/WerckerTrigger.tsx +0 -122
  46. package/src/pipeline/config/triggers/wercker/WerckerTriggerTemplate.tsx +0 -13
  47. package/src/pipeline/config/triggers/wercker/wercker.trigger.ts +0 -28
@@ -1,152 +0,0 @@
1
- import Spy = jasmine.Spy;
2
- import type { IControllerService, IQService, IRootScopeService, IScope } from 'angular';
3
- import { mock } from 'angular';
4
-
5
- import { IgorService } from '../../../../ci/igor.service';
6
- import type { IJobConfig, IParameterDefinitionList } from '../../../../domain';
7
- import { WERCKER_STAGE, WerckerStage } from './werckerStage';
8
-
9
- describe('Wercker Stage Controller', () => {
10
- let $scope: IScope, $q: IQService, $ctrl: IControllerService;
11
-
12
- beforeEach(mock.module(WERCKER_STAGE, require('angular-ui-bootstrap')));
13
-
14
- beforeEach(
15
- mock.inject(($controller: IControllerService, $rootScope: IRootScopeService, _$q_: IQService) => {
16
- $ctrl = $controller;
17
- $scope = $rootScope.$new();
18
- $q = _$q_;
19
- }),
20
- );
21
-
22
- const initialize = (stage: any): WerckerStage => {
23
- return $ctrl(WerckerStage, {
24
- stage,
25
- $scope,
26
- });
27
- };
28
-
29
- describe('updateAppsList', () => {
30
- beforeEach(() => {
31
- spyOn(IgorService, 'listMasters').and.returnValue($q.when([]));
32
- });
33
-
34
- it('does nothing if master is parameterized', () => {
35
- spyOn(IgorService, 'listJobsForMaster');
36
- const stage = {
37
- master: '${parameter.master}',
38
- };
39
- const controller = initialize(stage);
40
- $scope.$digest();
41
- expect(controller.jobs).toBeUndefined();
42
- expect(controller.viewState.appsLoaded).toBe(true);
43
- expect((IgorService.listJobsForMaster as Spy).calls.count()).toBe(0);
44
- });
45
-
46
- it('does nothing if job is parameterized', () => {
47
- spyOn(IgorService, 'listJobsForMaster');
48
- const stage = {
49
- master: 'not-parameterized',
50
- job: '${parameter.job}',
51
- };
52
- const controller = initialize(stage);
53
- $scope.$digest();
54
- expect(controller.jobs).toBeUndefined();
55
- expect(controller.viewState.appsLoaded).toBe(true);
56
- expect((IgorService.listJobsForMaster as Spy).calls.count()).toBe(0);
57
- });
58
-
59
- it('gets jobs from igor and adds them to scope', () => {
60
- const jobs = ['type/org/app/p1', 'type/org/app/p2'];
61
- spyOn(IgorService, 'listJobsForMaster').and.returnValue($q.when(jobs));
62
- const stage = {
63
- master: 'not-parameterized',
64
- };
65
- const controller = initialize(stage);
66
- $scope.$digest();
67
- expect(controller.jobs).toEqual(jobs);
68
- expect(controller.viewState.appsLoaded).toBe(true);
69
- });
70
-
71
- it('clears job if no longer present when retrieving from igor', () => {
72
- const jobs = ['type/org/app/a', 'type/org/app/b'];
73
- spyOn(IgorService, 'listJobsForMaster').and.returnValue($q.when(jobs));
74
- spyOn(IgorService, 'getJobConfig').and.returnValue($q.when(null));
75
- const stage = {
76
- master: 'not-parameterized',
77
- job: 'type/org/app/c',
78
- };
79
- const controller = initialize(stage);
80
- $scope.$digest();
81
- expect(controller.jobs).toEqual(jobs);
82
- expect(controller.viewState.appsLoaded).toBe(true);
83
- expect(stage.job).toBe('');
84
- });
85
- });
86
-
87
- describe('updateJobConfig', () => {
88
- beforeEach(() => {
89
- spyOn(IgorService, 'listMasters').and.returnValue($q.when([]));
90
- });
91
-
92
- it('does nothing if master is parameterized', () => {
93
- spyOn(IgorService, 'listJobsForMaster');
94
- spyOn(IgorService, 'getJobConfig');
95
- const stage = {
96
- master: '${parameter.master}',
97
- };
98
- const controller = initialize(stage);
99
- $scope.$digest();
100
- expect(controller.jobs).toBeUndefined();
101
- expect(controller.viewState.appsLoaded).toBe(true);
102
- expect((IgorService.listJobsForMaster as Spy).calls.count()).toBe(0);
103
- expect((IgorService.getJobConfig as Spy).calls.count()).toBe(0);
104
- });
105
-
106
- it('does nothing if job is parameterized', () => {
107
- spyOn(IgorService, 'listJobsForMaster');
108
- spyOn(IgorService, 'getJobConfig');
109
- const stage = {
110
- master: 'not-parameterized',
111
- job: '${parameter.job}',
112
- };
113
- const controller = initialize(stage);
114
- $scope.$digest();
115
- expect(controller.jobs).toBeUndefined();
116
- expect(controller.viewState.appsLoaded).toBe(true);
117
- expect((IgorService.listJobsForMaster as Spy).calls.count()).toBe(0);
118
- expect((IgorService.getJobConfig as Spy).calls.count()).toBe(0);
119
- });
120
-
121
- it('gets job config and adds parameters to scope, setting defaults if present and not overridden', () => {
122
- const jobs = ['type/org/app/x', 'type/org/app/y'];
123
- const params: IParameterDefinitionList[] = [
124
- { name: 'overridden', defaultValue: 'z' },
125
- { name: 'notSet', defaultValue: 'a' },
126
- { name: 'noDefault', defaultValue: null },
127
- ];
128
- const jobConfig = {
129
- parameterDefinitionList: params,
130
- } as IJobConfig;
131
- spyOn(IgorService, 'listJobsForMaster').and.returnValue($q.when(jobs));
132
- spyOn(IgorService, 'getJobConfig').and.returnValue($q.when(jobConfig));
133
- const stage = {
134
- master: 'not-parameterized',
135
- app: 'org/app',
136
- job: 'type/org/app/x',
137
- parameters: {
138
- overridden: 'f',
139
- },
140
- };
141
- const controller = initialize(stage);
142
- $scope.$digest();
143
- expect(controller.jobs).toEqual(jobs);
144
- expect(controller.viewState.appsLoaded).toBe(true);
145
- expect(controller.stage.job).toBe('type/org/app/x');
146
- expect(controller.jobParams).toBe(params);
147
- expect(controller.useDefaultParameters.overridden).toBeUndefined();
148
- expect(controller.useDefaultParameters.notSet).toBe(true);
149
- expect(controller.useDefaultParameters.noDefault).toBeUndefined();
150
- });
151
- });
152
- });
@@ -1,150 +0,0 @@
1
- <div class="form-horizontal">
2
- <div class="form-group">
3
- <label class="col-md-2 col-md-offset-1 sm-label-right">Build Service</label>
4
- <div class="col-md-6">
5
- <p class="form-control-static" ng-if="$ctrl.viewState.masterIsParameterized">{{$ctrl.stage.master}}</p>
6
- <ui-select
7
- class="form-control input-sm"
8
- ng-if="!$ctrl.viewState.masterIsParameterized"
9
- ng-model="$ctrl.stage.master"
10
- >
11
- <ui-select-match placeholder="Select a Wercker build service...">{{$select.selected}}</ui-select-match>
12
- <ui-select-choices repeat="master in $ctrl.masters | filter: $select.search">
13
- <span ng-bind-html="master | highlight: $select.search"></span>
14
- </ui-select-choices>
15
- </ui-select>
16
- </div>
17
- <div class="col-md-1 text-center" ng-if="!$ctrl.viewState.masterIsParameterized">
18
- <a
19
- href
20
- ng-click="$ctrl.refreshMasters()"
21
- tooltip-placement="right"
22
- uib-tooltip="{{$ctrl.viewState.mastersRefreshing ? 'Masters refreshing.' : 'Refresh masters list' }}"
23
- >
24
- <span ng-class="{'fa-spin':$ctrl.viewState.mastersRefreshing}" class="fa fa-sync-alt"></span>
25
- </a>
26
- </div>
27
- </div>
28
-
29
- <div class="form-group">
30
- <label class="col-md-2 col-md-offset-1 sm-label-right">Application</label>
31
- <div class="col-md-6">
32
- <p class="form-control-static" ng-if="!$ctrl.stage.master">(Select a build service)</p>
33
- <p
34
- class="form-control-static"
35
- ng-if="$ctrl.viewState.masterIsParameterized || $ctrl.viewState.appIsParameterized"
36
- >
37
- {{$ctrl.stage.app}}
38
- </p>
39
- <div ng-if="$ctrl.stage.master && $ctrl.viewState.appsLoaded">
40
- <ui-select
41
- class="form-control input-sm"
42
- ng-if="!$ctrl.viewState.masterIsParameterized && !$ctrl.viewState.appIsParameterized"
43
- ng-model="$ctrl.stage.app"
44
- >
45
- <ui-select-match placeholder="Select an Application...">{{$select.selected}}</ui-select-match>
46
- <ui-select-choices repeat="app in $ctrl.apps | filter: $select.search"
47
- ><span ng-bind-html="app | highlight: $select.search"></span
48
- ></ui-select-choices>
49
- </ui-select>
50
- </div>
51
- <div class="horizontal center" ng-if="$ctrl.stage.master && !$ctrl.viewState.appsLoaded">
52
- <loading-spinner size="'small'"></loading-spinner>
53
- </div>
54
- </div>
55
- <div
56
- class="col-md-1 text-center"
57
- ng-if="!$ctrl.viewState.masterIsParameterized && !$ctrl.viewState.appIsParameterized"
58
- >
59
- <a
60
- href
61
- ng-click="$ctrl.refreshApps()"
62
- tooltip-placement="right"
63
- uib-tooltip="{{$ctrl.viewState.appsRefreshing ? 'Applications refreshing.' : 'Refresh application list' }}"
64
- >
65
- <span ng-class="{'fa-spin':$ctrl.viewState.appsRefreshing}" class="fa fa-sync-alt"></span>
66
- </a>
67
- </div>
68
- </div>
69
-
70
- <div class="form-group">
71
- <label class="col-md-2 col-md-offset-1 sm-label-right">Pipeline</label>
72
- <div class="col-md-6">
73
- <p class="form-control-static" ng-if="!$ctrl.stage.master">(Select an Application)</p>
74
- <p
75
- class="form-control-static"
76
- ng-if="$ctrl.viewState.masterIsParameterized || $ctrl.viewState.jobIsParameterized"
77
- >
78
- {{stage.job}}
79
- </p>
80
- <div ng-if="$ctrl.stage.app && $ctrl.viewState.appsLoaded">
81
- <ui-select
82
- class="form-control input-sm"
83
- ng-if="!$ctrl.viewState.masterIsParameterized && !$ctrl.viewState.jobIsParameterized"
84
- ng-model="$ctrl.stage.pipeline"
85
- >
86
- <ui-select-match placeholder="Select a pipeline...">{{$select.selected}}</ui-select-match>
87
- <ui-select-choices repeat="pipeline in $ctrl.pipelines | filter: $select.search"
88
- ><span ng-bind-html="pipeline | highlight: $select.search"></span
89
- ></ui-select-choices>
90
- </ui-select>
91
- </div>
92
- <div class="horizontal center" ng-if="$ctrl.stage.app && !$ctrl.viewState.appsLoaded">
93
- <loading-spinner size="'small'"></loading-spinner>
94
- </div>
95
- </div>
96
- <div
97
- class="col-md-1 text-center"
98
- ng-if="!$ctrl.viewState.masterIsParameterized && !$ctrl.viewState.jobIsParameterized"
99
- >
100
- <a
101
- href
102
- ng-click="$ctrl.refreshJobs()"
103
- tooltip-placement="right"
104
- uib-tooltip="{{$ctrl.viewState.appsRefreshing ? 'Jobs refreshing.' : 'Refresh job list' }}"
105
- >
106
- <span ng-class="{'fa-spin':$ctrl.viewState.appsRefreshing}" class="fa fa-sync-alt"></span>
107
- </a>
108
- </div>
109
- </div>
110
-
111
- <stage-config-field label="Wait for results" help-key="wercker.waitForCompletion">
112
- <input
113
- type="checkbox"
114
- class="input-sm"
115
- name="waitForCompletion"
116
- ng-model="$ctrl.viewState.waitForCompletion"
117
- ng-change="$ctrl.waitForCompletionChanged()"
118
- />
119
- </stage-config-field>
120
-
121
- <div class="form-group">
122
- <label class="col-md-2 col-md-offset-1 sm-label-right">If build is unstable</label>
123
- <div class="col-md-9">
124
- <div class="radio">
125
- <label>
126
- <input
127
- type="radio"
128
- ng-model="$ctrl.viewState.markUnstableAsSuccessful"
129
- ng-change="$ctrl.markUnstableChanged()"
130
- ng-value="false"
131
- />
132
- fail the stage
133
- <help-field key="pipeline.config.wercker.markUnstableAsSuccessful.false"></help-field>
134
- </label>
135
- </div>
136
- <div class="radio">
137
- <label>
138
- <input
139
- type="radio"
140
- ng-model="$ctrl.viewState.markUnstableAsSuccessful"
141
- ng-change="$ctrl.markUnstableChanged()"
142
- ng-value="true"
143
- />
144
- consider stage successful
145
- <help-field key="pipeline.config.wercker.markUnstableAsSuccessful.true"></help-field>
146
- </label>
147
- </div>
148
- </div>
149
- </div>
150
- </div>
@@ -1,18 +0,0 @@
1
- import { module } from 'angular';
2
-
3
- import { STAGE_COMMON_MODULE } from '../common/stage.common.module';
4
- import { WERCKER_STAGE_ADD_PARAMETER_MODAL_CONTROLLER } from './modal/addParameter.controller.modal';
5
- import { CORE_PIPELINE_CONFIG_STAGES_STAGE_MODULE } from '../stage.module';
6
- import { TIME_FORMATTERS } from '../../../../utils/timeFormatters';
7
- import { WERCKER_EXECUTION_DETAILS_CONTROLLER } from './werckerExecutionDetails.controller';
8
- import { WERCKER_STAGE } from './werckerStage';
9
-
10
- export const WERCKER_STAGE_MODULE = 'spinnaker.core.pipeline.stage.wercker';
11
- module(WERCKER_STAGE_MODULE, [
12
- WERCKER_STAGE,
13
- CORE_PIPELINE_CONFIG_STAGES_STAGE_MODULE,
14
- STAGE_COMMON_MODULE,
15
- TIME_FORMATTERS,
16
- WERCKER_EXECUTION_DETAILS_CONTROLLER,
17
- WERCKER_STAGE_ADD_PARAMETER_MODAL_CONTROLLER,
18
- ]);
@@ -1,232 +0,0 @@
1
- import type { IController, IScope } from 'angular';
2
- import { module } from 'angular';
3
- import type { IModalService } from 'angular-ui-bootstrap';
4
-
5
- import { WerckerExecutionLabel } from './WerckerExecutionLabel';
6
- import { BuildServiceType, IgorService } from '../../../../ci/igor.service';
7
- import type { IJobConfig, IParameterDefinitionList, IStage } from '../../../../domain';
8
- import { Registry } from '../../../../registry';
9
-
10
- export interface IWerckerStageViewState {
11
- mastersLoaded: boolean;
12
- mastersRefreshing: boolean;
13
- appsLoaded: boolean;
14
- appsRefreshing: boolean;
15
- failureOption?: string;
16
- markUnstableAsSuccessful?: boolean;
17
- waitForCompletion?: boolean;
18
- masterIsParameterized?: boolean;
19
- jobIsParameterized?: boolean;
20
- }
21
-
22
- export interface IParameter {
23
- key: string;
24
- value: string;
25
- }
26
-
27
- export class WerckerStage implements IController {
28
- public viewState: IWerckerStageViewState;
29
- public useDefaultParameters: any;
30
- public userSuppliedParameters: any;
31
- public masters: string[];
32
- public jobs: string[];
33
- public jobParams: IParameterDefinitionList[];
34
- public apps: string[];
35
- public pipelines: string[];
36
- public filterLimit = 100;
37
- private filterThreshold = 500;
38
- public app: string;
39
- public pipeline: string;
40
- public job: string;
41
-
42
- public static $inject = ['stage', '$scope', '$uibModal'];
43
- constructor(public stage: any, $scope: IScope, private $uibModal: IModalService) {
44
- this.stage.failPipeline = this.stage.failPipeline === undefined ? true : this.stage.failPipeline;
45
- this.stage.continuePipeline = this.stage.continuePipeline === undefined ? false : this.stage.continuePipeline;
46
- this.viewState = {
47
- mastersLoaded: false,
48
- mastersRefreshing: false,
49
- appsLoaded: false,
50
- appsRefreshing: false,
51
- failureOption: 'fail',
52
- markUnstableAsSuccessful: !!this.stage.markUnstableAsSuccessful,
53
- waitForCompletion: this.stage.waitForCompletion || this.stage.waitForCompletion === undefined,
54
- };
55
- this.useDefaultParameters = {};
56
- this.userSuppliedParameters = {};
57
-
58
- this.initializeMasters();
59
-
60
- $scope.$watch('stage.master', () => this.updateAppsList());
61
- $scope.$watch('stage.app', () => this.updateJobsList());
62
- $scope.$watch('stage.pipeline', () => this.updateJob());
63
- $scope.$watch('stage.job', () => this.updateJobConfig());
64
- }
65
-
66
- // Using viewState to avoid marking pipeline as dirty if field is not set
67
- public markUnstableChanged(): void {
68
- this.stage.markUnstableAsSuccessful = this.viewState.markUnstableAsSuccessful;
69
- }
70
-
71
- public waitForCompletionChanged(): void {
72
- this.stage.waitForCompletion = this.viewState.waitForCompletion;
73
- }
74
-
75
- public refreshMasters(): void {
76
- this.viewState.mastersRefreshing = true;
77
- this.initializeMasters();
78
- }
79
-
80
- private initializeMasters(): void {
81
- IgorService.listMasters(BuildServiceType.Wercker).then((masters: string[]) => {
82
- this.masters = masters;
83
- this.viewState.mastersLoaded = true;
84
- this.viewState.mastersRefreshing = false;
85
- });
86
- }
87
-
88
- public refreshApps(): void {
89
- this.viewState.appsRefreshing = true;
90
- this.updateAppsList();
91
- }
92
-
93
- private updateAppsList(): void {
94
- const master = this.stage.master;
95
- const job: string = this.stage.job || '';
96
- const viewState = this.viewState;
97
- viewState.masterIsParameterized = master.includes('${');
98
- viewState.jobIsParameterized = job.includes('${');
99
- if (viewState.masterIsParameterized || viewState.jobIsParameterized) {
100
- viewState.appsLoaded = true;
101
- return;
102
- }
103
- if (this.stage && this.stage.master) {
104
- this.viewState.appsLoaded = false;
105
- this.apps = [];
106
- IgorService.listJobsForMaster(this.stage.master).then((jobs) => {
107
- this.viewState.appsLoaded = true;
108
- this.viewState.appsRefreshing = false;
109
- const apps = Object.create({});
110
- jobs.forEach(function (app) {
111
- const orgApp = app.substring(app.indexOf('/') + 1, app.lastIndexOf('/'));
112
- apps[orgApp] = orgApp;
113
- });
114
- this.apps = Object.keys(apps);
115
- this.jobs = jobs;
116
- if (this.apps.length && !this.apps.includes(this.stage.app)) {
117
- this.stage.app = '';
118
- this.stage.pipeline = '';
119
- this.stage.job = '';
120
- }
121
- });
122
- }
123
- }
124
-
125
- public refreshJobs(): void {
126
- this.viewState.appsRefreshing = true;
127
- this.updateJobsList();
128
- }
129
-
130
- private updateJobsList(): void {
131
- if (this.stage && this.stage.app) {
132
- this.pipelines = [];
133
- this.viewState.appsLoaded = true;
134
- this.viewState.appsRefreshing = false;
135
- if (this.jobs) {
136
- const pipelines = Object.create({});
137
- const appSelected = this.stage.app;
138
- this.jobs.forEach(function (app) {
139
- if (
140
- !app.startsWith('pipeline') &&
141
- appSelected === app.substring(app.indexOf('/') + 1, app.lastIndexOf('/'))
142
- ) {
143
- const pl = app.substring(app.lastIndexOf('/') + 1);
144
- pipelines[pl] = pl;
145
- }
146
- });
147
- this.pipelines = Object.keys(pipelines);
148
- }
149
- if (this.pipelines.length && !this.pipelines.includes(this.stage.pipeline)) {
150
- this.stage.pipeline = '';
151
- this.stage.job = '';
152
- }
153
- }
154
- }
155
-
156
- private updateJob(): void {
157
- if (this.stage && this.stage.app && this.stage.pipeline) {
158
- this.stage.job = this.stage.app + '/' + this.stage.pipeline;
159
- }
160
- }
161
-
162
- private updateJobConfig(): void {
163
- const stage = this.stage;
164
- const view = this.viewState;
165
- if (stage && stage.job && stage.master && !view.masterIsParameterized && !view.jobIsParameterized) {
166
- IgorService.getJobConfig(stage.master, stage.job).then((config: IJobConfig) => {
167
- config = config || ({} as IJobConfig);
168
- if (!stage.parameters) {
169
- stage.parameters = {};
170
- }
171
- this.jobParams = config.parameterDefinitionList;
172
- this.userSuppliedParameters = stage.parameters;
173
- this.useDefaultParameters = {};
174
- const params = this.jobParams || ([] as IParameterDefinitionList[]);
175
- params.forEach((property: any) => {
176
- if (!(property.name in stage.parameters) && property.defaultValue !== null) {
177
- this.useDefaultParameters[property.name] = true;
178
- }
179
- });
180
- });
181
- }
182
- }
183
-
184
- public addParameter(): void {
185
- this.$uibModal
186
- .open({
187
- templateUrl: require('./modal/addParameter.html'),
188
- controller: 'WerckerStageAddParameterCtrl',
189
- controllerAs: 'ctrl',
190
- })
191
- .result.then((parameter: IParameter) => {
192
- this.stage.parameters[parameter.key] = parameter.value;
193
- })
194
- .catch(() => {});
195
- }
196
-
197
- public removeParameter(key: string): void {
198
- delete this.stage.parameters[key];
199
- }
200
-
201
- public shouldFilter(): boolean {
202
- return this.jobs && this.jobs.length >= this.filterThreshold;
203
- }
204
- }
205
-
206
- export const WERCKER_STAGE = 'spinnaker.core.pipeline.stage.werckerStage';
207
-
208
- module(WERCKER_STAGE, [])
209
- .config(() => {
210
- Registry.pipeline.registerStage({
211
- label: 'Wercker',
212
- description: 'Runs a Wercker build pipeline',
213
- key: 'wercker',
214
- restartable: true,
215
- controller: 'WerckerStageCtrl',
216
- controllerAs: '$ctrl',
217
- templateUrl: require('./werckerStage.html'),
218
- executionDetailsUrl: require('./werckerExecutionDetails.html'),
219
- executionLabelComponent: WerckerExecutionLabel,
220
- extraLabelLines: (stage: IStage) => {
221
- if (!stage.masterStage.context || !stage.masterStage.context.buildInfo) {
222
- return 0;
223
- }
224
- const lines = stage.masterStage.context.buildInfo.number ? 1 : 0;
225
- return lines + (stage.masterStage.context.buildInfo.testResults || []).length;
226
- },
227
- supportsCustomTimeout: true,
228
- validators: [{ type: 'requiredField', fieldName: 'job' }],
229
- strategy: true,
230
- });
231
- })
232
- .controller('WerckerStageCtrl', WerckerStage);
@@ -1,122 +0,0 @@
1
- import type { FormikProps } from 'formik';
2
- import { uniq } from 'lodash';
3
- import React from 'react';
4
-
5
- import { RefreshableReactSelectInput } from '../RefreshableReactSelectInput';
6
- import type { Application } from '../../../../application';
7
- import type { IBaseBuildTriggerConfigProps } from '../baseBuild/BaseBuildTrigger';
8
- import { BuildServiceType, IgorService } from '../../../../ci/igor.service';
9
- import type { IWerckerTrigger } from '../../../../domain';
10
- import { FormikFormField, ReactSelectInput, useLatestPromise } from '../../../../presentation';
11
-
12
- export interface IWerckerTriggerConfigProps extends IBaseBuildTriggerConfigProps {
13
- formik: FormikProps<IWerckerTrigger>;
14
- trigger: IWerckerTrigger;
15
- application: Application;
16
- pipelineId: string;
17
- triggerUpdated: (trigger: IWerckerTrigger) => void;
18
- }
19
-
20
- // given a job name i.e., "git/organization/repo/job" or "pipeline/organization/repo/jobname"
21
- // returns { app: 'organization/repo', pipeline: 'job' } or { app: 'organization/repo', pipeline: 'jobname' }
22
- function getJobParts(job: string) {
23
- const firstSlash = job.indexOf('/');
24
- const lastSlash = job.lastIndexOf('/');
25
-
26
- const app = job.substring(firstSlash + 1, lastSlash);
27
- const pipeline = job.substring(lastSlash + 1);
28
- return { app, pipeline };
29
- }
30
-
31
- export function WerckerTrigger(werckerTriggerProps: IWerckerTriggerConfigProps) {
32
- const { formik } = werckerTriggerProps;
33
- const { app, master, pipeline } = formik.values;
34
-
35
- const fetchMasters = useLatestPromise(() => IgorService.listMasters(BuildServiceType.Wercker), []);
36
-
37
- const mastersLoading = fetchMasters.status === 'PENDING';
38
- const mastersLoaded = fetchMasters.status === 'RESOLVED';
39
-
40
- const fetchJobs = useLatestPromise(() => {
41
- return master && IgorService.listJobsForMaster(master).then((x) => x.map(getJobParts));
42
- }, [master]);
43
-
44
- const jobs = fetchJobs.result;
45
- const jobsLoading = fetchJobs.status === 'PENDING';
46
- const jobsLoaded = fetchJobs.status === 'RESOLVED';
47
-
48
- const apps = React.useMemo(() => {
49
- return jobsLoaded ? uniq(jobs.map((job) => job.app)) : [];
50
- }, [jobsLoaded, jobs]);
51
-
52
- const pipelines = React.useMemo(() => {
53
- return jobsLoaded ? jobs.filter((parts) => parts.app === app).map((parts) => parts.pipeline) : [];
54
- }, [jobsLoaded, app, jobs]);
55
-
56
- // Clear out app or pipeline if they aren't in the fetched jobs data
57
- React.useEffect(() => {
58
- if (jobsLoaded && !!app && !apps.includes(app)) {
59
- formik.setFieldValue('app', null);
60
- }
61
- if (jobsLoaded && !!pipeline && !pipelines.includes(pipeline)) {
62
- formik.setFieldValue('pipeline', null);
63
- }
64
- }, [jobsLoaded, apps, app, pipelines, pipeline]);
65
-
66
- // Update 'job' field when pipeline or app changes
67
- React.useEffect(() => {
68
- const hasJob = !!app && !!pipeline;
69
- const job = hasJob ? `${app}/${pipeline}` : null;
70
- formik.setFieldValue('job', job);
71
- }, [pipeline, app]);
72
-
73
- return (
74
- <>
75
- <FormikFormField
76
- name="master"
77
- label="Build Service"
78
- input={(props) => (
79
- <RefreshableReactSelectInput
80
- {...props}
81
- stringOptions={fetchMasters.result}
82
- placeholder={'Select a build service...'}
83
- disabled={!mastersLoaded}
84
- isLoading={mastersLoading}
85
- onRefreshClicked={() => fetchMasters.refresh()}
86
- refreshButtonTooltipText={mastersLoading ? 'Masters refreshing' : 'Refresh masters list'}
87
- />
88
- )}
89
- />
90
-
91
- <FormikFormField
92
- name="app"
93
- label="Application"
94
- input={(props) => (
95
- <RefreshableReactSelectInput
96
- {...props}
97
- stringOptions={apps}
98
- placeholder={'Select an application...'}
99
- disabled={!master || !jobsLoaded}
100
- isLoading={jobsLoading}
101
- onRefreshClicked={() => fetchJobs.refresh()}
102
- refreshButtonTooltipText={jobsLoading ? 'Apps refreshing' : 'Refresh app list'}
103
- />
104
- )}
105
- />
106
-
107
- <FormikFormField
108
- name="pipeline"
109
- label="Pipeline"
110
- input={(props) => (
111
- <ReactSelectInput
112
- {...props}
113
- disabled={!master || !jobsLoaded}
114
- isLoading={jobsLoading}
115
- stringOptions={pipelines}
116
- placeholder="Select a pipeline"
117
- />
118
- )}
119
- />
120
- </>
121
- );
122
- }
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
-
3
- import { BaseBuildTriggerTemplate } from '../baseBuild/BaseBuildTriggerTemplate';
4
- import { BuildServiceType } from '../../../../ci';
5
- import type { ITriggerTemplateComponentProps } from '../../../manualExecution/TriggerTemplate';
6
-
7
- export class WerckerTriggerTemplate extends React.Component<ITriggerTemplateComponentProps> {
8
- public static formatLabel = BaseBuildTriggerTemplate.formatLabel;
9
-
10
- public render() {
11
- return <BaseBuildTriggerTemplate {...this.props} buildTriggerType={BuildServiceType.Wercker} />;
12
- }
13
- }