55 push :
66 branches :
77 - main
8+ tags :
9+ - ' v*'
810
911concurrency :
1012 group : ${{ github.workflow }}-${{ github.ref }}
3638
3739 permissions :
3840 actions : write
39- contents : read
41+ contents : write
4042 id-token : write # Required for OIDC token request to AWS STS
4143
4244 runs-on : ubuntu-latest
6264 with :
6365 role-to-assume : ${{ secrets.AWS_CODEBUILD_ROLE_ARN }}
6466 aws-region : ${{ vars.AWS_REGION || 'us-east-1' }}
65- role-duration-seconds : 7200
67+ role-duration-seconds : ${{ vars.ROLE_DURATION_SECONDS || 7200 }}
6668 role-session-name : GitHubActions${{ github.run_id }}
6769 mask-aws-account-id : true
70+ retry-max-attempts : 0
6871
6972 - name : Run CodeBuild
7073 if : steps.cache-check.outputs.cache-hit != 'true'
@@ -77,61 +80,90 @@ jobs:
7780 version: 0.2
7881 env:
7982 variables:
80- TEST_ONE: "1"
83+ GH_TOKEN: ${{ github.token }}
8184 phases:
8285 install:
8386 commands:
84- - echo "install ${TEST_ONE}" | tee --append ./codebuild.out
85- - dnf install -y lshw || echo "dnf install failed"
87+ - dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo || echo "dnf config-manager"
88+ - dnf install -y 'dnf-command(config-manager)' gh || echo "dnf install failed"
89+ - curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=$HOME/.local/bin:$PATH || "echo uv failed"
8690 pre_build:
8791 commands:
88- - echo "pre_build ${TEST_ONE}" | tee --append ./codebuild.out
89- - echo "=== OS ==="
90- - cat /etc/os-release
91- - echo "=== Kernel ==="
92- - uname -a
93- - echo "=== CPU ==="
94- - lscpu
95- - echo "=== Memory ==="
96- - free -h
97- - echo "=== Disk ==="
98- - df -h
99- - echo "=== Block Devices ==="
100- - lsblk
101- - echo "=== Hardware Summary ==="
102- - lshw -short || echo "lshw failed"
92+ - echo "pre_build"
93+ - mkdir -p .codebuild
94+ - touch .codebuild/codebuild.out
95+ - git config --global --add safe.directory "/codebuild/output/srcDownload/src" # for running AWS CodeBuild locally
10396 build:
10497 commands:
105- - echo "build ${TEST_ONE}" | tee --append ./codebuild.out
106- - ls -alR
98+ - DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
99+ - CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
100+ - CURRENT_TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
101+ - IS_RELEASE=$([[ -n "$CURRENT_TAG" ]] && echo "true" || echo "false")
102+ - IS_PRE_RELEASE=$([[ "$CURRENT_BRANCH" == "$DEFAULT_BRANCH" ]] && echo "true" || echo "false")
103+ - IS_PRE_MERGE=$([[ -z "$CURRENT_TAG" && "$CURRENT_BRANCH" != "$DEFAULT_BRANCH" ]] && echo "true" || echo "false")
104+ - if [[ "$IS_RELEASE" == "true" ]]; then echo "This is a release"; fi;
105+ - if [[ "$IS_PRE_RELEASE" == "true" ]]; then echo "This is a pre-release"; fi;
106+ - if [[ "$IS_PRE_MERGE" == "true" ]]; then echo "This is a pre-merge"; fi;
107+ - mkdir -p .codebuild/evaluation
108+ - mkdir -p .codebuild/trend
109+ - mkdir -p .codebuild/missing
110+ - touch .codebuild/evaluation/evaluation_report.html
111+ - touch .codebuild/evaluation/metrics.yml
112+ - touch .codebuild/trend/trend_report.html
107113 post_build:
108114 commands:
109- - echo "post_build ${TEST_ONE}" | tee --append ./codebuild.out
110115 - echo "Build completed with status $CODEBUILD_BUILD_SUCCEEDING"
111- - cat ./codebuild.out
116+ - cat ./.codebuild/ codebuild.out
112117 artifacts:
113118 files:
114- - '**/codebuild.out'
115- discard-paths: yes
119+ - '**/*'
120+ discard-paths: no
121+ base-directory: .codebuild
122+ secondary-artifacts:
123+ evaluation:
124+ files:
125+ - '**/*'
126+ name: evaluation
127+ discard-paths: yes
128+ base-directory: .codebuild/evaluation
129+ trend:
130+ files:
131+ - '**/*'
132+ name: trend
133+ discard-paths: yes
134+ base-directory: .codebuild/trend
116135
117136 - name : Build ID
118137 if : always() && steps.cache-check.outputs.cache-hit != 'true'
119138 run : echo "CodeBuild Build ID ${{ steps.codebuild.outputs.aws-build-id }}"
120139
121- - name : Download CodeBuild artifact
140+ - name : Download CodeBuild artifacts
122141 if : steps.cache-check.outputs.cache-hit != 'true'
123142 run : |
124- ARTIFACT_LOCATION=$(aws codebuild batch-get-builds \
143+ DOWNLOADS="${ACT_CODEBUILD_DIR:-${GITHUB_WORKSPACE}/.codebuild/downloads}"
144+ mkdir -p "$DOWNLOADS"
145+ PRIMARY_ARTIFACT_LOCATION=$(aws codebuild batch-get-builds \
125146 --ids "${{ steps.codebuild.outputs.aws-build-id }}" \
126147 --query 'builds[0].artifacts.location' \
127148 --output text)
128- aws s3 cp "s3://${ARTIFACT_LOCATION#arn:aws:s3:::}" ./${{ env.CODEBUILD_PROJECT_NAME }}.zip
149+ aws s3 cp "s3://${PRIMARY_ARTIFACT_LOCATION#arn:aws:s3:::}" "$DOWNLOADS/${{ env.CODEBUILD_PROJECT_NAME }}.zip"
150+ SECONDARY_ARTIFACT_LOCATIONS=$(aws codebuild batch-get-builds \
151+ --ids "${{ steps.codebuild.outputs.aws-build-id }}" \
152+ --query 'builds[0].secondaryArtifacts[*].[artifactIdentifier, location]' \
153+ --output json)
154+ echo "$SECONDARY_ARTIFACT_LOCATIONS" | jq -r '.[] | @tsv' | while IFS=$'\t' read -r NAME LOCATION; do
155+ echo "Downloading secondary artifact: $NAME"
156+ aws s3 cp "s3://${LOCATION#arn:aws:s3:::}" "$DOWNLOADS/${NAME}.zip"
157+ done
129158
130159 - name : List CodeBuild artifacts
131160 if : steps.cache-check.outputs.cache-hit != 'true'
132161 run : |
133- ls -alR
134- unzip -l ${{ env.CODEBUILD_PROJECT_NAME }}.zip
162+ DOWNLOADS="${ACT_CODEBUILD_DIR:-${GITHUB_WORKSPACE}/.codebuild/downloads}"
163+ ls -alR "$DOWNLOADS"
164+ unzip -l "$DOWNLOADS/${{ env.CODEBUILD_PROJECT_NAME }}.zip"
165+ unzip -l "$DOWNLOADS/evaluation.zip"
166+ unzip -l "$DOWNLOADS/trend.zip"
135167
136168 - name : Clean old report caches
137169 if : steps.cache-check.outputs.cache-hit != 'true'
@@ -147,5 +179,77 @@ jobs:
147179 if : steps.cache-check.outputs.cache-hit != 'true'
148180 uses : actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
149181 with :
150- path : ${{ env.CODEBUILD_PROJECT_NAME }}.zip
182+ path : ${{ github.workspace }}/.codebuild/downloads/${{ env.CODEBUILD_PROJECT_NAME }}.zip
151183 key : ${{ env.CODEBUILD_PROJECT_NAME }}-${{ github.ref_name }}-${{ github.sha }}
184+
185+ - name : Upload CodeBuild primary artifact
186+ if : ${{ !env.ACT }} # incompatability with v6 of upload-artifact and act
187+ uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
188+ with :
189+ name : ${{ env.CODEBUILD_PROJECT_NAME }}.zip
190+ path : ${{ github.workspace }}/.codebuild/downloads/${{ env.CODEBUILD_PROJECT_NAME }}.zip
191+ if-no-files-found : error
192+
193+ - name : Upload CodeBuild secondary artifact - evaluation
194+ if : ${{ !env.ACT }} # incompatability with v6 of upload-artifact and act
195+ uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
196+ with :
197+ name : evaluation.zip
198+ path : ${{ github.workspace }}/.codebuild/downloads/evaluation.zip
199+ if-no-files-found : error
200+
201+ - name : Upload CodeBuild secondary artifact - trend
202+ if : ${{ !env.ACT }} # incompatability with v6 of upload-artifact and act
203+ uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
204+ with :
205+ name : trend.zip
206+ path : ${{ github.workspace }}/.codebuild/downloads/trend.zip
207+ if-no-files-found : error
208+
209+ - name : Upload artifacts to release
210+ if : startsWith(github.ref, 'refs/tags/v')
211+ env :
212+ GH_TOKEN : ${{ github.token }}
213+ TAG : ${{ github.ref_name }}
214+ REPO : ${{ github.repository }}
215+ run : |
216+ DOWNLOADS="${GITHUB_WORKSPACE}/.codebuild/downloads"
217+ ARTIFACTS=(
218+ "$DOWNLOADS/${{ env.CODEBUILD_PROJECT_NAME }}.zip"
219+ "$DOWNLOADS/evaluation.zip"
220+ "$DOWNLOADS/trend.zip"
221+ )
222+
223+ # Wait for release to exist (release.yml typically finishes in ~30s,
224+ # CodeBuild takes minutes — this is a safety net)
225+ RELEASE_EXISTS=false
226+ for i in $(seq 1 30); do
227+ if gh release view "$TAG" --repo "$REPO" --json isDraft,tagName &>/dev/null; then
228+ RELEASE_EXISTS=true
229+ break
230+ fi
231+ echo "Waiting for release $TAG (attempt $i/30)..."
232+ sleep 10
233+ done
234+
235+ if [[ "$RELEASE_EXISTS" == "true" ]]; then
236+ # Release exists (draft or published) — upload/replace artifacts
237+ IS_DRAFT=$(gh release view "$TAG" --repo "$REPO" --json isDraft --jq '.isDraft')
238+ if [[ "$IS_DRAFT" == "true" ]]; then
239+ echo "Draft release $TAG found — uploading artifacts"
240+ else
241+ echo "Published release $TAG found — attempting to replace artifacts"
242+ fi
243+ gh release upload "$TAG" "${ARTIFACTS[@]}" --repo "$REPO" --clobber || {
244+ echo "WARNING: Failed to upload artifacts to release $TAG (release may be immutable)"
245+ echo "Artifacts are still available as workflow artifacts above"
246+ }
247+ else
248+ # No release exists — create a draft with artifacts
249+ echo "No release found for $TAG — creating draft release with artifacts"
250+ gh release create "$TAG" "${ARTIFACTS[@]}" \
251+ --repo "$REPO" \
252+ --draft \
253+ --title "AI-DLC Workflow ${TAG#v}" \
254+ --notes "Build artifacts from CodeBuild. Rules zip pending from release workflow."
255+ fi
0 commit comments