11import os
2- import sys
2+ import urllib3
3+ from urllib3 .util .retry import Retry
4+ from urllib3 .exceptions import HTTPError
35
46import yaml
57
68YAML_HEADER = '# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json\n '
79
10+ def fetch_version_qualifier_url_with_retries (branch , max_retries = 3 , backoff_factor = 2 ):
11+ """
12+ Return the version qualifier from a centralized URL based on branch. For any failure or response apart from 200,
13+ assume no qualifier (return empty string).
14+ """
15+ url = f"https://storage.googleapis.com/dra-qualifier/{ branch } "
16+
17+ http = urllib3 .PoolManager ()
18+
19+ # Configure retries: Exponential backoff with 3 retries
20+ retries = Retry (
21+ total = max_retries ,
22+ backoff_factor = backoff_factor , # Wait time increases exponentially (2, 4, 8s)
23+ status_forcelist = [500 , 502 , 503 , 504 ], # Retry only on server errors
24+ raise_on_status = False # Do not raise exception on failed status codes
25+ )
26+
27+ try :
28+ response = http .request ("GET" , url , retries = retries , timeout = 5 )
29+ if response .status == 200 :
30+ return response .data .decode ("utf-8" ).strip ()
31+ except HTTPError as e :
32+ pass
33+
34+ return ""
35+
836def to_bk_key_friendly_string (key ):
937 """
1038 Convert and return key to an acceptable format for Buildkite's key: field
@@ -15,7 +43,7 @@ def to_bk_key_friendly_string(key):
1543
1644 return key .translate (mapping_table )
1745
18- def package_x86_step (branch , workflow_type ):
46+ def package_x86_step (branch , workflow_type , version_qualifier ):
1947 step = f'''
2048- label: ":package: Build packages / { branch } -{ workflow_type .upper ()} DRA artifacts"
2149 key: "logstash_build_packages_dra"
@@ -27,14 +55,15 @@ def package_x86_step(branch, workflow_type):
2755 diskSizeGb: 200
2856 command: |
2957 export WORKFLOW_TYPE="{ workflow_type } "
58+ export VERSION_QUALIFIER="{ version_qualifier } "
3059 export PATH="/opt/buildkite-agent/.rbenv/bin:/opt/buildkite-agent/.pyenv/bin:$PATH"
3160 eval "$(rbenv init -)"
3261 .buildkite/scripts/dra/build_packages.sh
3362'''
3463
3564 return step
3665
37- def package_x86_docker_step (branch , workflow_type ):
66+ def package_x86_docker_step (branch , workflow_type , version_qualifier ):
3867 step = f'''
3968- label: ":package: Build x86_64 Docker / { branch } -{ workflow_type .upper ()} DRA artifacts"
4069 key: "logstash_build_x86_64_docker_dra"
@@ -46,6 +75,7 @@ def package_x86_docker_step(branch, workflow_type):
4675 diskSizeGb: 200
4776 command: |
4877 export WORKFLOW_TYPE="{ workflow_type } "
78+ export VERSION_QUALIFIER="{ version_qualifier } "
4979 export PATH="/opt/buildkite-agent/.rbenv/bin:/opt/buildkite-agent/.pyenv/bin:$PATH"
5080 export ARCH="x86_64"
5181 eval "$(rbenv init -)"
@@ -54,7 +84,7 @@ def package_x86_docker_step(branch, workflow_type):
5484
5585 return step
5686
57- def package_aarch64_docker_step (branch , workflow_type ):
87+ def package_aarch64_docker_step (branch , workflow_type , version_qualifier ):
5888 step = f'''
5989- label: ":package: Build aarch64 Docker / { branch } -{ workflow_type .upper ()} DRA artifacts"
6090 key: "logstash_build_aarch64_docker_dra"
@@ -65,6 +95,7 @@ def package_aarch64_docker_step(branch, workflow_type):
6595 diskSizeGb: 200
6696 command: |
6797 export WORKFLOW_TYPE="{ workflow_type } "
98+ export VERSION_QUALIFIER="{ version_qualifier } "
6899 export PATH="/opt/buildkite-agent/.rbenv/bin:/opt/buildkite-agent/.pyenv/bin:$PATH"
69100 export ARCH="aarch64"
70101 eval "$(rbenv init -)"
@@ -73,7 +104,7 @@ def package_aarch64_docker_step(branch, workflow_type):
73104
74105 return step
75106
76- def publish_dra_step (branch , workflow_type , depends_on ):
107+ def publish_dra_step (branch , workflow_type , depends_on , version_qualifier ):
77108 step = f'''
78109- label: ":elastic-stack: Publish / { branch } -{ workflow_type .upper ()} DRA artifacts"
79110 key: "logstash_publish_dra"
@@ -92,50 +123,59 @@ def publish_dra_step(branch, workflow_type, depends_on):
92123 sudo chown -R :1000 build
93124 echo "+++ Running DRA publish step"
94125 export WORKFLOW_TYPE="{ workflow_type } "
126+ export VERSION_QUALIFIER="{ version_qualifier } "
95127 .buildkite/scripts/dra/publish.sh
96128 '''
97129
98130 return step
99131
100- def build_steps_to_yaml (branch , workflow_type ):
132+ def build_steps_to_yaml (branch , workflow_type , version_qualifier ):
101133 steps = []
102- steps .extend (yaml .safe_load (package_x86_step (branch , workflow_type )))
103- steps .extend (yaml .safe_load (package_x86_docker_step (branch , workflow_type )))
104- steps .extend (yaml .safe_load (package_aarch64_docker_step (branch , workflow_type )))
134+ steps .extend (yaml .safe_load (package_x86_step (branch , workflow_type , version_qualifier )))
135+ steps .extend (yaml .safe_load (package_x86_docker_step (branch , workflow_type , version_qualifier )))
136+ steps .extend (yaml .safe_load (package_aarch64_docker_step (branch , workflow_type , version_qualifier )))
105137
106138 return steps
107139
108140if __name__ == "__main__" :
141+ # DRA_BRANCH can be used for manually testing packaging with PRs
142+ # e.g. define `DRA_BRANCH="main"` under Options/Environment Variables in the Buildkite UI after clicking new Build
143+ branch = os .environ .get ("DRA_BRANCH" , os .environ ["BUILDKITE_BRANCH" ])
144+
109145 try :
110146 workflow_type = os .environ ["WORKFLOW_TYPE" ]
111- version_qualifier = os .environ .get ("VERSION_QUALIFIER" , "" )
112147 except ImportError :
113148 print (f"Missing env variable WORKFLOW_TYPE. Use export WORKFLOW_TYPE=<staging|snapshot>\n .Exiting." )
114149 exit (1 )
115150
116- branch = os .environ ["BUILDKITE_BRANCH" ]
151+ # allow manually set version qualifier via BK env vars (should be rarely used, only for testing)
152+ version_qualifier = os .environ .get ("VERSION_QUALIFIER" , "" )
117153
118154 structure = {"steps" : []}
119155
120156 if workflow_type .upper () == "SNAPSHOT" and len (version_qualifier )> 0 :
157+ # externally set VERSION_QUALIFIER is NOT allowed with SNAPSHOT DRA. Skip.
121158 structure ["steps" ].append ({
122159 "label" : f"no-op pipeline because prerelease builds (VERSION_QUALIFIER is set to [{ version_qualifier } ]) don't support the [{ workflow_type } ] workflow" ,
123160 "command" : ":" ,
124161 "skip" : "VERSION_QUALIFIER (prerelease builds) not supported with SNAPSHOT DRA" ,
125162 })
126163 else :
164+ if workflow_type .upper () == "STAGING" and len (version_qualifier )== 0 :
165+ version_qualifier = fetch_version_qualifier_url_with_retries (branch )
166+
127167 # Group defining parallel steps that build and save artifacts
128168 group_key = to_bk_key_friendly_string (f"logstash_dra_{ workflow_type } " )
129169
130170 structure ["steps" ].append ({
131171 "group" : f":Build Artifacts - { workflow_type .upper ()} " ,
132172 "key" : group_key ,
133- "steps" : build_steps_to_yaml (branch , workflow_type ),
173+ "steps" : build_steps_to_yaml (branch , workflow_type , version_qualifier ),
134174 })
135175
136176 # Final step: pull artifacts built above and publish them via the release-manager
137177 structure ["steps" ].extend (
138- yaml .safe_load (publish_dra_step (branch , workflow_type , depends_on = group_key )),
178+ yaml .safe_load (publish_dra_step (branch , workflow_type , depends_on = group_key , version_qualifier = version_qualifier )),
139179 )
140180
141181 print (YAML_HEADER + yaml .dump (structure , Dumper = yaml .Dumper , sort_keys = False ))
0 commit comments