This is an automated email from the ASF dual-hosted git repository.
shwstppr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git
The following commit(s) were added to refs/heads/main by this push:
new 547b8a3 github-action: add pr builder for easier testing (#178)
547b8a3 is described below
commit 547b8a39299eb57e3c6750581bdc6eac3cb928eb
Author: Abhishek Kumar <[email protected]>
AuthorDate: Fri Aug 8 15:29:51 2025 +0530
github-action: add pr builder for easier testing (#178)
Adds a Github action to build binaries for easier testing of PRs. A comment
will be added in the PR.
Workflow runs on `pull_request_target` and has two jobs - build, comment.
`comment` job needs issues:write permission due to which the workflow can
run only when it is present on main.
`build` job only has read permission to prevent insecure permissions
Tested here: https://github.com/shwstppr/cloudstack-cloudmonkey/pull/3
Signed-off-by: Abhishek Kumar <[email protected]>
---
.github/workflows/build-pr-cmk.yml | 120 +++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/.github/workflows/build-pr-cmk.yml
b/.github/workflows/build-pr-cmk.yml
new file mode 100644
index 0000000..c95d59a
--- /dev/null
+++ b/.github/workflows/build-pr-cmk.yml
@@ -0,0 +1,120 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Build cmk binaries on PR
+
+on:
+ pull_request_target:
+ types: [opened, synchronize, reopened]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ permissions:
+ contents: read
+ runs-on: ubuntu-24.04
+ env:
+ GITHUB_TOKEN: ""
+ outputs:
+ outcome: ${{ steps.meta.outputs.outcome }}
+ artifact_url: ${{ steps.meta.outputs.artifact_url }}
+ steps:
+ - name: Checkout PR HEAD
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ persist-credentials: false
+
+ - name: Set up Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: '1.22'
+
+ - name: Build dist
+ id: build
+ run: make dist
+ continue-on-error: true
+
+ - name: Upload zipped dist artifact
+ id: upload_artifact
+ if: ${{ steps.build.outcome == 'success' }} # gate on build outcome
+ uses: actions/upload-artifact@v4
+ with:
+ name: cmk-binaries.pr${{ github.event.pull_request.number }}
+ path: dist/
+ if-no-files-found: error
+ retention-days: 10
+
+ - name: Expose build outcome & artifact link
+ id: meta
+ if: always()
+ run: |
+ echo "outcome=${{ steps.build.outcome }}" >> $GITHUB_OUTPUT
+ echo "artifact_url=${{ steps.upload_artifact.outputs.artifact-url
}}" >> $GITHUB_OUTPUT
+
+ comment:
+ if: always()
+ needs: build
+ permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+ runs-on: ubuntu-24.04
+ steps:
+ - name: Comment or update cmk build artifact on PR
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const { execSync } = require('child_process');
+
+ const issue_number = context.payload.pull_request.number;
+ const identifier = "cmk-build-artifact-comment";
+
+ const owner = context.payload.repository.owner.login; // base repo
(pull_request_target)
+ const repo = context.payload.repository.name;
+
+ const buildOutcome = "${{ needs.build.outputs.outcome }}";
+ const artifactUrl = "${{ needs.build.outputs.artifact_url }}";
+ const runId = "${{ github.run_id }}";
+
+ core.info(`Will comment on ${owner}/${repo}#${issue_number}`);
+ core.info(`Outcome=${buildOutcome || '(empty)'}
Artifact=${artifactUrl || '(none)'}`);
+
+ let body = `<!-- ${identifier} -->\n`;
+ if (buildOutcome === 'success' && artifactUrl) {
+ const expiryDate = execSync("date -d '+10 days' '+%B %d,
%Y'").toString().trim();
+ body += `✅ Build complete for PR #${issue_number}.\n\n`;
+ body += `🔗 Download the [cmk binaries](${artifactUrl}) (expires
on ${expiryDate})`;
+ } else {
+ body += `❌ Build failed for PR #${issue_number}.\n\n`;
+ body += `See the run:
https://github.com/${owner}/${repo}/actions/runs/${runId}`;
+ }
+
+ const { data: comments } = await github.rest.issues.listComments({
owner, repo, issue_number });
+ const existing = comments.find(c => c.user.login ===
'github-actions[bot]' && c.body.includes(identifier));
+
+ if (existing) {
+ core.info(`Updating comment id ${existing.id}`);
+ await github.rest.issues.updateComment({ owner, repo,
comment_id: existing.id, body });
+ } else {
+ core.info(`Creating new comment`);
+ await github.rest.issues.createComment({ owner, repo,
issue_number, body });
+ }
+