@shipfox/client-workflows 19.0.0 → 20.0.0

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 (50) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +14 -0
  3. package/dist/components/workflow-run-duration-label.d.ts +8 -7
  4. package/dist/components/workflow-run-duration-label.d.ts.map +1 -1
  5. package/dist/components/workflow-run-duration-label.js +15 -31
  6. package/dist/components/workflow-run-duration-label.js.map +1 -1
  7. package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
  8. package/dist/components/workflow-run-list/workflow-run-row.js +9 -6
  9. package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
  10. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
  11. package/dist/components/workflow-run-summary/workflow-run-summary.js +7 -34
  12. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
  13. package/dist/components/workflow-status/status-visuals.d.ts.map +1 -1
  14. package/dist/components/workflow-status/status-visuals.js +0 -9
  15. package/dist/components/workflow-status/status-visuals.js.map +1 -1
  16. package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -1
  17. package/dist/components/workflow-status/workflow-status-icon.js +0 -11
  18. package/dist/components/workflow-status/workflow-status-icon.js.map +1 -1
  19. package/dist/core/entities/workflow-run.d.ts +10 -55
  20. package/dist/core/entities/workflow-run.d.ts.map +1 -1
  21. package/dist/core/entities/workflow-run.js +1 -94
  22. package/dist/core/entities/workflow-run.js.map +1 -1
  23. package/dist/core/workflow-run.d.ts +2 -2
  24. package/dist/core/workflow-run.d.ts.map +1 -1
  25. package/dist/core/workflow-run.js +1 -1
  26. package/dist/core/workflow-run.js.map +1 -1
  27. package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
  28. package/dist/hooks/api/workflow-run-mapper.js +3 -1
  29. package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
  30. package/dist/hooks/api/workflow-runs.js +1 -0
  31. package/dist/hooks/api/workflow-runs.js.map +1 -1
  32. package/dist/tsconfig.test.tsbuildinfo +1 -1
  33. package/package.json +2 -2
  34. package/src/components/workflow-run-duration-label.tsx +21 -44
  35. package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +48 -0
  36. package/src/components/workflow-run-list/workflow-run-row.tsx +7 -6
  37. package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +0 -38
  38. package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +73 -21
  39. package/src/components/workflow-run-summary/workflow-run-summary.tsx +6 -27
  40. package/src/components/workflow-status/status-visuals.ts +0 -4
  41. package/src/components/workflow-status/workflow-status-icon.stories.tsx +0 -1
  42. package/src/components/workflow-status/workflow-status-icon.tsx +0 -18
  43. package/src/core/entities/workflow-run.ts +9 -136
  44. package/src/core/workflow-run.test.ts +2 -0
  45. package/src/core/workflow-run.ts +0 -8
  46. package/src/hooks/api/workflow-run-mapper.ts +2 -0
  47. package/src/hooks/api/workflow-runs.ts +1 -1
  48. package/test/fixtures/workflow-run.ts +30 -3
  49. package/tsconfig.build.tsbuildinfo +1 -1
  50. package/src/core/entities/workflow-run-display.test.ts +0 -187
@@ -1,187 +0,0 @@
1
- import {
2
- workflowJob,
3
- workflowJobExecutionDto,
4
- workflowRunJobsFixture,
5
- workflowRunListItem,
6
- } from '#test/fixtures/workflow-run.js';
7
- import {
8
- workflowRunBlockingJob,
9
- workflowRunDetailDisplay,
10
- workflowRunListItemDisplay,
11
- } from './workflow-run.js';
12
-
13
- const ATTEMPT_STARTED_AT = '2026-05-07T01:00:00.000Z';
14
- const WORK_STARTED_AT = '2026-05-07T01:02:00.000Z';
15
- const FINISHED_AT = '2026-05-07T01:05:00.000Z';
16
-
17
- describe('workflowRunDetailDisplay', () => {
18
- test('reads a running attempt whose jobs have not started as queued', () => {
19
- const display = workflowRunDetailDisplay(
20
- runDetail({jobs: [pendingJob()], startedAt: ATTEMPT_STARTED_AT}),
21
- );
22
-
23
- expect(display.status).toBe('queued');
24
- expect(display.duration).toEqual({kind: 'queue', state: 'live', fromIso: ATTEMPT_STARTED_AT});
25
- });
26
-
27
- test('measures run time from the first execution, not from the attempt', () => {
28
- const display = workflowRunDetailDisplay(
29
- runDetail({
30
- jobs: [startedJob(), pendingJob()],
31
- startedAt: ATTEMPT_STARTED_AT,
32
- }),
33
- );
34
-
35
- expect(display.status).toBe('running');
36
- expect(display.duration).toEqual({kind: 'run', state: 'live', fromIso: WORK_STARTED_AT});
37
- });
38
-
39
- test('does not treat skipped jobs as started work', () => {
40
- const display = workflowRunDetailDisplay(
41
- runDetail({
42
- jobs: [workflowJob({key: 'skipped', status: 'skipped'}), pendingJob()],
43
- startedAt: ATTEMPT_STARTED_AT,
44
- }),
45
- );
46
-
47
- expect(display.status).toBe('queued');
48
- expect(display.duration).toMatchObject({kind: 'queue'});
49
- });
50
-
51
- test('keeps the queue reading for a run cancelled before anything started', () => {
52
- const display = workflowRunDetailDisplay(
53
- runDetail({
54
- status: 'cancelled',
55
- jobs: [pendingJob()],
56
- startedAt: ATTEMPT_STARTED_AT,
57
- finishedAt: FINISHED_AT,
58
- }),
59
- );
60
-
61
- expect(display.status).toBe('cancelled');
62
- expect(display.duration).toMatchObject({kind: 'queue', state: 'fixed'});
63
- });
64
-
65
- test('does not claim a queue when the run carries no jobs to prove one', () => {
66
- const display = workflowRunDetailDisplay(runDetail({jobs: [], startedAt: ATTEMPT_STARTED_AT}));
67
-
68
- expect(display.status).toBe('running');
69
- expect(display.duration).toEqual({kind: 'run', state: 'live', fromIso: ATTEMPT_STARTED_AT});
70
- });
71
-
72
- test('has no duration before the attempt starts', () => {
73
- expect(workflowRunDetailDisplay(runDetail({jobs: [pendingJob()]})).duration).toBeNull();
74
- });
75
- });
76
-
77
- describe('workflowRunListItemDisplay', () => {
78
- test('reaches the detail page verdict from job status counts alone', () => {
79
- const run = workflowRunListItem({
80
- status: 'running',
81
- ...workflowRunJobsFixture(['pending', 'pending']),
82
- started_at: ATTEMPT_STARTED_AT,
83
- });
84
-
85
- const display = workflowRunListItemDisplay(run);
86
-
87
- expect(display.status).toBe('queued');
88
- expect(display.duration).toEqual({kind: 'queue', state: 'live', fromIso: ATTEMPT_STARTED_AT});
89
- });
90
-
91
- test('stays running once any job has left pending', () => {
92
- const run = workflowRunListItem({
93
- status: 'running',
94
- ...workflowRunJobsFixture(['succeeded', 'pending']),
95
- started_at: ATTEMPT_STARTED_AT,
96
- });
97
-
98
- const display = workflowRunListItemDisplay(run);
99
-
100
- expect(display.status).toBe('running');
101
- expect(display.duration).toMatchObject({kind: 'run'});
102
- });
103
-
104
- test('uses execution-derived running counts for the row headline', () => {
105
- const run = workflowRunListItem({
106
- status: 'running',
107
- ...workflowRunJobsFixture(['pending']),
108
- job_display_status_counts: [{status: 'running', count: 1}],
109
- started_at: ATTEMPT_STARTED_AT,
110
- });
111
-
112
- const display = workflowRunListItemDisplay(run);
113
-
114
- expect(display.status).toBe('running');
115
- expect(display.duration).toMatchObject({kind: 'run'});
116
- });
117
-
118
- test('uses execution-derived listening counts as started work', () => {
119
- const run = workflowRunListItem({
120
- status: 'running',
121
- ...workflowRunJobsFixture(['pending']),
122
- job_display_status_counts: [{status: 'listening', count: 1}],
123
- started_at: ATTEMPT_STARTED_AT,
124
- });
125
-
126
- const display = workflowRunListItemDisplay(run);
127
-
128
- expect(display.status).toBe('running');
129
- expect(display.duration).toMatchObject({kind: 'run'});
130
- });
131
- });
132
-
133
- describe('workflowRunBlockingJob', () => {
134
- test('ignores finished queued executions when finding the blocking job', () => {
135
- const historicalJob = workflowJob({
136
- key: 'historical',
137
- job_executions: [
138
- workflowJobExecutionDto({
139
- status: 'succeeded',
140
- queued_at: '2026-05-07T00:59:00.000Z',
141
- finished_at: '2026-05-07T01:00:00.000Z',
142
- }),
143
- ],
144
- });
145
- const currentJob = workflowJob({
146
- key: 'current',
147
- job_executions: [workflowJobExecutionDto({queued_at: '2026-05-07T01:01:00.000Z'})],
148
- });
149
-
150
- expect(workflowRunBlockingJob([historicalJob, currentJob])?.key).toBe('current');
151
- });
152
- });
153
-
154
- function pendingJob() {
155
- return workflowJob({
156
- key: 'lint',
157
- job_executions: [workflowJobExecutionDto({queued_at: ATTEMPT_STARTED_AT})],
158
- });
159
- }
160
-
161
- function startedJob() {
162
- return workflowJob({
163
- key: 'build',
164
- status: 'running',
165
- job_executions: [
166
- workflowJobExecutionDto({
167
- status: 'running',
168
- queued_at: ATTEMPT_STARTED_AT,
169
- started_at: WORK_STARTED_AT,
170
- }),
171
- ],
172
- });
173
- }
174
-
175
- function runDetail({
176
- status = 'running',
177
- jobs,
178
- startedAt = null,
179
- finishedAt = null,
180
- }: {
181
- status?: 'running' | 'cancelled';
182
- jobs: ReturnType<typeof workflowJob>[];
183
- startedAt?: string | null;
184
- finishedAt?: string | null;
185
- }) {
186
- return {runAttempt: {status, startedAt, finishedAt}, jobs};
187
- }