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 });
+            }
+

Reply via email to