Skip to content

Commit f530c59

Browse files
author
Taniya Mathur
committed
Implement version-based pipeline execution tracking
- Replace timing-based execution ID lookup with S3 version ID matching - Update Makefile to capture S3 version ID during upload and save to .upload_version_id - Add get_execution_id_by_version method to find execution by S3 version ID - Remove old get_execution_id_after_trigger method - Ensures each parallel pipeline tracks its own specific execution - Eliminates race conditions in parallel execution monitoring
1 parent bff60fe commit f530c59

File tree

2 files changed

+34
-50
lines changed

2 files changed

+34
-50
lines changed

scripts/sdlc/idp-cli/Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,18 @@ smoketest:
3636
--stack-name=$(IDP_STACK_NAME)
3737

3838
wait:
39-
$(eval EXECUTION_ID := $(shell poetry run python -c "from idp_cli.util.codepipeline_util import CodePipelineUtil; print(CodePipelineUtil.get_execution_id_after_trigger('$(IDP_PIPELINE_NAME)'))"))
39+
$(eval VERSION_ID := $(shell cat $(IDP_CWD)/.upload_version_id 2>/dev/null || echo ""))
40+
$(eval EXECUTION_ID := $(shell poetry run python -c "from idp_cli.util.codepipeline_util import CodePipelineUtil; print(CodePipelineUtil.get_execution_id_by_version('$(IDP_PIPELINE_NAME)', '$(VERSION_ID)'))"))
4041
poetry run idpcli monitor-pipeline \
4142
--pipeline-name=$(IDP_PIPELINE_NAME) \
4243
--execution-id=$(EXECUTION_ID) \
4344
--initial-wait=0 \
4445
--max-wait=120
4546

4647
put: zip
47-
cd $(IDP_CWD) && \
48-
aws s3 cp ./dist/code.zip s3://$(SDLC_SOURCE_CODE_BUCKET)/deploy/code.zip --force
48+
$(eval VERSION_ID := $(shell cd $(IDP_CWD) && aws s3api put-object --bucket $(SDLC_SOURCE_CODE_BUCKET) --key deploy/code.zip --body ./dist/code.zip --query 'VersionId' --output text))
49+
@echo "Uploaded with version ID: $(VERSION_ID)"
50+
@echo "$(VERSION_ID)" > $(IDP_CWD)/.upload_version_id
4951

5052
zip:
5153
cd $(IDP_CWD) && \

scripts/sdlc/idp-cli/src/idp_cli/util/codepipeline_util.py

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,52 +8,6 @@
88

99
class CodePipelineUtil:
1010
@staticmethod
11-
def get_execution_id_after_trigger(pipeline_name, wait_seconds=30):
12-
"""Get the execution ID after S3 upload triggers the pipeline"""
13-
import time
14-
client = boto3.client('codepipeline')
15-
16-
# Record trigger time
17-
trigger_time = time.time()
18-
retry_count = 5
19-
20-
for attempt in range(retry_count):
21-
# Wait for pipeline to start
22-
time.sleep(wait_seconds)
23-
24-
# Get recent executions and find InProgress one closest to our trigger time
25-
response = client.list_pipeline_executions(pipelineName=pipeline_name, maxResults=5)
26-
executions = response.get('pipelineExecutionSummaries', [])
27-
28-
if not executions:
29-
if attempt < retry_count - 1:
30-
continue # Try again
31-
raise Exception(f"No executions found for pipeline '{pipeline_name}'")
32-
33-
# Find InProgress execution that started closest to our trigger time
34-
best_execution = None
35-
min_time_diff = float('inf')
36-
37-
for execution in executions:
38-
# Only consider InProgress executions
39-
if execution['status'] != 'InProgress':
40-
continue
41-
42-
start_time = execution['startTime'].timestamp()
43-
time_diff = abs(start_time - trigger_time)
44-
45-
if time_diff < min_time_diff:
46-
min_time_diff = time_diff
47-
best_execution = execution
48-
49-
if best_execution:
50-
return best_execution['pipelineExecutionId']
51-
elif attempt < retry_count - 1:
52-
continue # Try again after another wait
53-
54-
# No InProgress execution found after retries
55-
raise Exception(f"No InProgress execution found for pipeline '{pipeline_name}' after {trigger_time}")
56-
5711
@staticmethod
5812
def wait_for_pipeline_execution(pipeline_name, execution_id=None, initial_wait_seconds=10, poll_interval_seconds=30, max_wait_minutes=90):
5913
"""
@@ -322,4 +276,32 @@ def get_stage_logs(pipeline_name, stage_name, execution_id=None, max_lines=1024)
322276
all_logs.extend(logs)
323277
all_logs.append("") # Add a blank line between actions
324278

325-
return all_logs
279+
return all_logs
280+
281+
@staticmethod
282+
def get_execution_id_by_version(pipeline_name, version_id, wait_seconds=30):
283+
"""Get execution ID by matching S3 version ID"""
284+
import time
285+
client = boto3.client('codepipeline')
286+
287+
if not version_id:
288+
raise Exception("Version ID is required")
289+
290+
retry_count = 5
291+
292+
for attempt in range(retry_count):
293+
time.sleep(wait_seconds)
294+
295+
response = client.list_pipeline_executions(pipelineName=pipeline_name, maxResults=10)
296+
executions = response.get('pipelineExecutionSummaries', [])
297+
298+
for execution in executions:
299+
source_revisions = execution.get('sourceRevisions', [])
300+
if source_revisions and source_revisions[0].get('revisionId') == version_id:
301+
logger.info(f"Found execution {execution['pipelineExecutionId']} for version {version_id}")
302+
return execution['pipelineExecutionId']
303+
304+
if attempt < retry_count - 1:
305+
logger.info(f"Version {version_id} not found, retrying... (attempt {attempt + 1}/{retry_count})")
306+
307+
raise Exception(f"No execution found for version ID {version_id}")

0 commit comments

Comments
 (0)