Skip to content

Commit 1ff445a

Browse files
feat(codepipeline): add AWS CodePipeline integration with tools and block (#4945)
* feat(codepipeline): add AWS CodePipeline integration with tools and block * fix(codepipeline): address review feedback on input coercion and error statuses * chore(hooks): restore use-inline-rename onSave type accidentally swept into previous commit
1 parent 3cedac8 commit 1ff445a

40 files changed

Lines changed: 3227 additions & 2 deletions

apps/docs/components/icons.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5512,6 +5512,33 @@ export function CloudWatchIcon(props: SVGProps<SVGSVGElement>) {
55125512
)
55135513
}
55145514

5515+
export function CodePipelineIcon(props: SVGProps<SVGSVGElement>) {
5516+
return (
5517+
<svg
5518+
{...props}
5519+
viewBox='5 5 70.002 70.002'
5520+
version='1.1'
5521+
xmlns='http://www.w3.org/2000/svg'
5522+
xmlnsXlink='http://www.w3.org/1999/xlink'
5523+
>
5524+
<g
5525+
id='Icon-Architecture/64/Arch_AWS-CodePipeline_64'
5526+
stroke='none'
5527+
strokeWidth='1'
5528+
fill='none'
5529+
fillRule='evenodd'
5530+
transform='translate(40, 40) scale(1.25) translate(-40, -40)'
5531+
>
5532+
<path
5533+
d='M30,31 L35,31 L35,29 L30,29 L30,31 Z M36.667,61.166 L34.817,60.407 L42.409,41.885 L44.259,42.644 L36.667,61.166 Z M45.571,55.78 L51.068,50.958 L45.575,46.197 L46.886,44.685 L53.245,50.198 C53.463,50.387 53.589,50.662 53.590006,50.951 C53.591,51.24 53.467,51.515 53.249,51.706 L46.89,57.284 L45.571,55.78 Z M25.508976,51.048 C25.507,50.759 25.63,50.484 25.847,50.293 L32.184,44.691 L33.508,46.19 L28.029,51.033 L33.478,55.73 L32.171,57.245 L25.855,51.799 C25.637,51.611 25.511,51.337 25.508976,51.048 L25.508976,51.048 Z M62.535,35 L18.465,35 C16.555,35 15,33.446 15,31.536 L15,31 L27,31 L27,29 L15,29 L15,18.464 C15,16.554 16.555,15 18.465,15 L62.535,15 C64.445,15 66,16.554 66,18.464 L66,29 L38,29 L38,31 L66,31 L66,31.536 C66,33.446 64.445,35 62.535,35 L62.535,35 Z M22,66 L58,66 L58,37 L22,37 L22,66 Z M62.535,13 L18.465,13 C15.451,13 13,15.451 13,18.464 L13,31.536 C13,34.549 15.451,37 18.465,37 L20,37 L20,67 C20,67.552 20.447,68 21,68 L59,68 C59.553,68 60,67.552 60,67 L60,37 L62.535,37 C65.549,37 68,34.549 68,31.536 L68,18.464 C68,15.451 65.549,13 62.535,13 L62.535,13 Z'
5534+
id='AWS-CodePipeline_Icon_64_Squid'
5535+
fill='currentColor'
5536+
/>
5537+
</g>
5538+
</svg>
5539+
)
5540+
}
5541+
55155542
export function TextractIcon(props: SVGProps<SVGSVGElement>) {
55165543
return (
55175544
<svg

apps/docs/components/ui/icon-mapping.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
CloudFormationIcon,
3636
CloudflareIcon,
3737
CloudWatchIcon,
38+
CodePipelineIcon,
3839
ConfluenceIcon,
3940
CrowdStrikeIcon,
4041
CursorIcon,
@@ -249,6 +250,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
249250
cloudflare: CloudflareIcon,
250251
cloudformation: CloudFormationIcon,
251252
cloudwatch: CloudWatchIcon,
253+
codepipeline: CodePipelineIcon,
252254
confluence: ConfluenceIcon,
253255
confluence_v2: ConfluenceIcon,
254256
crowdstrike: CrowdStrikeIcon,
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
---
2+
title: CodePipeline
3+
description: Run, monitor, and approve AWS CodePipeline pipelines
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="codepipeline"
10+
color="linear-gradient(45deg, #2E27AD 0%, #527FFF 100%)"
11+
/>
12+
13+
## Usage Instructions
14+
15+
Integrate AWS CodePipeline into workflows. Start, stop, and monitor pipeline executions, retry failed stages, and approve or reject manual approval actions. Requires AWS access key and secret access key.
16+
17+
18+
19+
## Tools
20+
21+
### `codepipeline_list_pipelines`
22+
23+
List all CodePipeline pipelines in an AWS account and region
24+
25+
#### Input
26+
27+
| Parameter | Type | Required | Description |
28+
| --------- | ---- | -------- | ----------- |
29+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
30+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
31+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
32+
| `maxResults` | number | No | Maximum number of pipelines to return \(1-1000\) |
33+
| `nextToken` | string | No | Pagination token from a previous call |
34+
35+
#### Output
36+
37+
| Parameter | Type | Description |
38+
| --------- | ---- | ----------- |
39+
| `pipelines` | array | List of pipelines with name, version, type, and timestamps |
40+
|`name` | string | Pipeline name |
41+
|`version` | number | Pipeline version number |
42+
|`pipelineType` | string | Pipeline type \(V1 or V2\) |
43+
|`executionMode` | string | Execution mode \(QUEUED, SUPERSEDED, PARALLEL\) |
44+
|`created` | number | Epoch ms when the pipeline was created |
45+
|`updated` | number | Epoch ms when the pipeline was last updated |
46+
| `nextToken` | string | Pagination token for the next page of results |
47+
48+
### `codepipeline_get_pipeline_state`
49+
50+
Get the current state of a CodePipeline pipeline, including stage and action status and pending approval tokens
51+
52+
#### Input
53+
54+
| Parameter | Type | Required | Description |
55+
| --------- | ---- | -------- | ----------- |
56+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
57+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
58+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
59+
| `pipelineName` | string | Yes | Name of the pipeline |
60+
61+
#### Output
62+
63+
| Parameter | Type | Description |
64+
| --------- | ---- | ----------- |
65+
| `pipelineName` | string | Pipeline name |
66+
| `pipelineVersion` | number | Pipeline version number |
67+
| `created` | number | Epoch ms when the pipeline was created |
68+
| `updated` | number | Epoch ms when the pipeline was last updated |
69+
| `stageStates` | array | Per-stage state including latest execution status and action details |
70+
|`stageName` | string | Stage name |
71+
|`status` | string | Latest stage execution status \(InProgress, Succeeded, Failed, Stopped, Cancelled\) |
72+
|`pipelineExecutionId` | string | Pipeline execution ID currently in the stage |
73+
|`inboundTransitionEnabled` | boolean | Whether the inbound transition into the stage is enabled |
74+
|`actionStates` | array | Per-action state with status, summary, error details, and approval token \(for pending manual approvals\) |
75+
76+
### `codepipeline_get_pipeline_execution`
77+
78+
Get details of a CodePipeline execution, including status, trigger, source revisions, and resolved variables
79+
80+
#### Input
81+
82+
| Parameter | Type | Required | Description |
83+
| --------- | ---- | -------- | ----------- |
84+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
85+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
86+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
87+
| `pipelineName` | string | Yes | Name of the pipeline |
88+
| `pipelineExecutionId` | string | Yes | ID of the pipeline execution |
89+
90+
#### Output
91+
92+
| Parameter | Type | Description |
93+
| --------- | ---- | ----------- |
94+
| `pipelineExecutionId` | string | Pipeline execution ID |
95+
| `pipelineName` | string | Pipeline name |
96+
| `pipelineVersion` | number | Pipeline version number |
97+
| `status` | string | Execution status \(Cancelled, InProgress, Stopped, Stopping, Succeeded, Superseded, Failed\) |
98+
| `statusSummary` | string | Status summary for the execution |
99+
| `executionMode` | string | Execution mode \(QUEUED, SUPERSEDED, PARALLEL\) |
100+
| `executionType` | string | Execution type \(STANDARD or ROLLBACK\) |
101+
| `triggerType` | string | What triggered the execution \(e.g., Webhook, StartPipelineExecution\) |
102+
| `triggerDetail` | string | Detail about the trigger \(e.g., user ARN\) |
103+
| `artifactRevisions` | array | Source artifact revisions for the execution |
104+
|`name` | string | Artifact name |
105+
|`revisionId` | string | Revision ID \(e.g., commit SHA\) |
106+
|`revisionSummary` | string | Revision summary \(e.g., commit message\) |
107+
|`revisionUrl` | string | URL of the revision |
108+
|`created` | number | Epoch ms when the revision was created |
109+
| `variables` | array | Resolved pipeline variables for the execution |
110+
|`name` | string | Variable name |
111+
|`resolvedValue` | string | Resolved variable value |
112+
113+
### `codepipeline_list_pipeline_executions`
114+
115+
List recent executions of a CodePipeline pipeline with status and source revisions
116+
117+
#### Input
118+
119+
| Parameter | Type | Required | Description |
120+
| --------- | ---- | -------- | ----------- |
121+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
122+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
123+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
124+
| `pipelineName` | string | Yes | Name of the pipeline |
125+
| `maxResults` | number | No | Maximum number of executions to return \(1-100, default 100\) |
126+
| `nextToken` | string | No | Pagination token from a previous call |
127+
| `succeededInStage` | string | No | Only return executions that succeeded in this stage |
128+
129+
#### Output
130+
131+
| Parameter | Type | Description |
132+
| --------- | ---- | ----------- |
133+
| `executions` | array | Pipeline execution summaries, most recent first |
134+
|`pipelineExecutionId` | string | Pipeline execution ID |
135+
|`status` | string | Execution status \(Cancelled, InProgress, Stopped, Stopping, Succeeded, Superseded, Failed\) |
136+
|`statusSummary` | string | Status summary for the execution |
137+
|`startTime` | number | Epoch ms when the execution started |
138+
|`lastUpdateTime` | number | Epoch ms when the execution was last updated |
139+
|`executionMode` | string | Execution mode \(QUEUED, SUPERSEDED, PARALLEL\) |
140+
|`executionType` | string | Execution type \(STANDARD or ROLLBACK\) |
141+
|`stopTriggerReason` | string | Reason the execution was stopped, if applicable |
142+
|`triggerType` | string | What triggered the execution |
143+
|`triggerDetail` | string | Detail about the trigger |
144+
|`sourceRevisions` | array | Source revisions \(commit IDs, summaries, URLs\) for the execution |
145+
| `nextToken` | string | Pagination token for the next page of results |
146+
147+
### `codepipeline_start_execution`
148+
149+
Start a CodePipeline pipeline execution, optionally overriding pipeline variables
150+
151+
#### Input
152+
153+
| Parameter | Type | Required | Description |
154+
| --------- | ---- | -------- | ----------- |
155+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
156+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
157+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
158+
| `pipelineName` | string | Yes | Name of the pipeline to start |
159+
| `clientRequestToken` | string | No | Idempotency token to identify a unique execution request |
160+
| `variables` | json | No | Pipeline variable overrides as an array of \{ name, value \} objects |
161+
162+
#### Output
163+
164+
| Parameter | Type | Description |
165+
| --------- | ---- | ----------- |
166+
| `pipelineExecutionId` | string | ID of the pipeline execution that was started |
167+
168+
### `codepipeline_stop_execution`
169+
170+
Stop a CodePipeline pipeline execution, either finishing in-progress actions or abandoning them
171+
172+
#### Input
173+
174+
| Parameter | Type | Required | Description |
175+
| --------- | ---- | -------- | ----------- |
176+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
177+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
178+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
179+
| `pipelineName` | string | Yes | Name of the pipeline |
180+
| `pipelineExecutionId` | string | Yes | ID of the pipeline execution to stop |
181+
| `abandon` | boolean | No | Abandon in-progress actions instead of letting them finish \(default false\) |
182+
| `reason` | string | No | Reason for stopping the execution \(max 200 characters\) |
183+
184+
#### Output
185+
186+
| Parameter | Type | Description |
187+
| --------- | ---- | ----------- |
188+
| `pipelineExecutionId` | string | ID of the pipeline execution that was stopped |
189+
190+
### `codepipeline_retry_stage_execution`
191+
192+
Retry the failed actions (or all actions) of a failed CodePipeline stage
193+
194+
#### Input
195+
196+
| Parameter | Type | Required | Description |
197+
| --------- | ---- | -------- | ----------- |
198+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
199+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
200+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
201+
| `pipelineName` | string | Yes | Name of the pipeline |
202+
| `stageName` | string | Yes | Name of the failed stage to retry |
203+
| `pipelineExecutionId` | string | Yes | ID of the pipeline execution in the failed stage |
204+
| `retryMode` | string | Yes | Scope of the retry: FAILED_ACTIONS or ALL_ACTIONS |
205+
206+
#### Output
207+
208+
| Parameter | Type | Description |
209+
| --------- | ---- | ----------- |
210+
| `pipelineExecutionId` | string | ID of the pipeline execution with the retried stage |
211+
212+
### `codepipeline_put_approval_result`
213+
214+
Approve or reject a pending CodePipeline manual approval action. The approval token is available from Get Pipeline State on the pending approval action
215+
216+
#### Input
217+
218+
| Parameter | Type | Required | Description |
219+
| --------- | ---- | -------- | ----------- |
220+
| `awsRegion` | string | Yes | AWS region \(e.g., us-east-1\) |
221+
| `awsAccessKeyId` | string | Yes | AWS access key ID |
222+
| `awsSecretAccessKey` | string | Yes | AWS secret access key |
223+
| `pipelineName` | string | Yes | Name of the pipeline |
224+
| `stageName` | string | Yes | Name of the stage containing the approval action |
225+
| `actionName` | string | Yes | Name of the manual approval action |
226+
| `token` | string | Yes | Approval token from Get Pipeline State for the pending approval |
227+
| `status` | string | Yes | Approval decision: Approved or Rejected |
228+
| `summary` | string | Yes | Summary explaining the approval decision \(max 512 characters\) |
229+
230+
#### Output
231+
232+
| Parameter | Type | Description |
233+
| --------- | ---- | ----------- |
234+
| `approvedAt` | number | Epoch ms when the approval or rejection was submitted |
235+
| `status` | string | The submitted approval decision \(Approved or Rejected\) |
236+
237+

apps/docs/content/docs/en/tools/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"cloudflare",
3131
"cloudformation",
3232
"cloudwatch",
33+
"codepipeline",
3334
"confluence",
3435
"crowdstrike",
3536
"cursor",
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { CodePipelineClient, GetPipelineExecutionCommand } from '@aws-sdk/client-codepipeline'
2+
import { createLogger } from '@sim/logger'
3+
import { toError } from '@sim/utils/errors'
4+
import { type NextRequest, NextResponse } from 'next/server'
5+
import { awsCodepipelineGetPipelineExecutionContract } from '@/lib/api/contracts/tools/aws/codepipeline-get-pipeline-execution'
6+
import { parseToolRequest } from '@/lib/api/server'
7+
import { checkInternalAuth } from '@/lib/auth/hybrid'
8+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
9+
import { awsErrorStatus } from '@/app/api/tools/codepipeline/utils'
10+
11+
const logger = createLogger('CodePipelineGetPipelineExecution')
12+
13+
export const POST = withRouteHandler(async (request: NextRequest) => {
14+
try {
15+
const auth = await checkInternalAuth(request)
16+
if (!auth.success || !auth.userId) {
17+
return NextResponse.json({ error: auth.error || 'Unauthorized' }, { status: 401 })
18+
}
19+
20+
const parsed = await parseToolRequest(awsCodepipelineGetPipelineExecutionContract, request, {
21+
errorFormat: 'details',
22+
logger,
23+
})
24+
if (!parsed.success) return parsed.response
25+
const validatedData = parsed.data.body
26+
27+
logger.info('Getting CodePipeline pipeline execution')
28+
29+
const client = new CodePipelineClient({
30+
region: validatedData.region,
31+
credentials: {
32+
accessKeyId: validatedData.accessKeyId,
33+
secretAccessKey: validatedData.secretAccessKey,
34+
},
35+
})
36+
37+
try {
38+
const command = new GetPipelineExecutionCommand({
39+
pipelineName: validatedData.pipelineName,
40+
pipelineExecutionId: validatedData.pipelineExecutionId,
41+
})
42+
43+
const response = await client.send(command)
44+
const execution = response.pipelineExecution
45+
46+
if (!execution) {
47+
throw new Error('Pipeline execution not found in response')
48+
}
49+
50+
logger.info('Successfully got pipeline execution')
51+
52+
return NextResponse.json({
53+
success: true,
54+
output: {
55+
pipelineExecutionId: execution.pipelineExecutionId ?? validatedData.pipelineExecutionId,
56+
pipelineName: execution.pipelineName ?? validatedData.pipelineName,
57+
pipelineVersion: execution.pipelineVersion,
58+
status: execution.status ?? 'Unknown',
59+
statusSummary: execution.statusSummary,
60+
executionMode: execution.executionMode,
61+
executionType: execution.executionType,
62+
triggerType: execution.trigger?.triggerType,
63+
triggerDetail: execution.trigger?.triggerDetail,
64+
artifactRevisions: (execution.artifactRevisions ?? []).map((r) => ({
65+
name: r.name ?? '',
66+
revisionId: r.revisionId,
67+
revisionSummary: r.revisionSummary,
68+
revisionUrl: r.revisionUrl,
69+
created: r.created?.getTime(),
70+
})),
71+
variables: (execution.variables ?? []).map((v) => ({
72+
name: v.name ?? '',
73+
resolvedValue: v.resolvedValue ?? '',
74+
})),
75+
},
76+
})
77+
} finally {
78+
client.destroy()
79+
}
80+
} catch (error) {
81+
logger.error('GetPipelineExecution failed', { error: toError(error).message })
82+
return NextResponse.json(
83+
{ error: `Failed to get CodePipeline pipeline execution: ${toError(error).message}` },
84+
{ status: awsErrorStatus(error) }
85+
)
86+
}
87+
})

0 commit comments

Comments
 (0)