Skip to content

Commit 5b3da3e

Browse files
authored
Add Quick Access to images comment to PRs (#1133)
* Add Quick Access to images comment to PRs * Refactor Image comment workflow to use shared script pattern. Also refactors away dead crud. * Refine comment output and normalise names to prevent bugs. * Fix PR comment writing not working. * Please the linter * Remove Sha Tag due to it going stale if any branch movement happens.
1 parent a1a8537 commit 5b3da3e

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com>
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
/**
6+
* @param {Object} args
7+
* @param {import('@actions/github').getOctokit} args.github
8+
* @param {import('@actions/github').context} args.context
9+
* @param {import('@actions/core')} args.core
10+
*/
11+
module.exports = async ({ github, context, core }) => {
12+
const pullRequest = context.payload.pull_request;
13+
if (!pullRequest) {
14+
core.notice("No pull_request payload found; skipping.");
15+
return;
16+
}
17+
18+
const marker = "<!-- ghcr-pr-image-link -->";
19+
const repo = context.repo.repo;
20+
const ownerContext = context.repo.owner;
21+
const prNumber = pullRequest.number;
22+
23+
// prOwner is a bit confusingly named it could be argued. Its Head Branch Owner effectively.
24+
// It is used to determine the GHCR namespace for the PR build.
25+
// In most cases this will be the same as the repo owner,
26+
// but in fork scenarios it will be different and we want to ensure the GHCR namespace is correct,
27+
// to keep this workflow functional for its intended purpose of providing image refs for PRs independently of origin.
28+
const prOwner = pullRequest.head?.repo?.owner?.login || ownerContext;
29+
const branch = pullRequest.head?.ref || "";
30+
const sha = pullRequest.head?.sha || context.sha;
31+
const shortSha = sha.substring(0, 7);
32+
const normalizedBranch = branch.replace(/\//g, "-");
33+
34+
const lowerOwner = prOwner.toLowerCase();
35+
const lowerRepo = repo.toLowerCase();
36+
37+
const imageNamespace = `ghcr.io/${lowerOwner}/${lowerRepo}`;
38+
// The root package URL on GitHub. We can't link to the exact version ID without querying the GH API,
39+
// so we link to the package landing page where the user can see the recent tags.
40+
const packageUrl = `https://github.com/${prOwner}/${repo}/pkgs/container/${lowerRepo}`;
41+
42+
const branchTag = normalizedBranch || shortSha;
43+
44+
const body = [
45+
`GHCR image refs for this PR:`,
46+
"",
47+
`- Namespace: \`${imageNamespace}\``,
48+
`- Branch tag: \`${branchTag}\``,
49+
`- Package Page: [GHCR Link](${packageUrl})`,
50+
`- Pull: \`docker pull ${imageNamespace}:${branchTag}\``,
51+
"",
52+
`This comment is generated from PR metadata only. It does not checkout or run PR code and is generated in a static manner`,
53+
marker,
54+
].join("\n");
55+
56+
// Update or create comments
57+
const comments = await github.rest.issues.listComments({
58+
owner: ownerContext,
59+
repo,
60+
issue_number: prNumber,
61+
per_page: 100,
62+
});
63+
64+
const existingComment = comments.data.find(
65+
(comment) =>
66+
comment.user?.type === "Bot" &&
67+
typeof comment.body === "string" &&
68+
comment.body.includes(marker)
69+
);
70+
71+
if (existingComment) {
72+
await github.rest.issues.updateComment({
73+
owner: ownerContext,
74+
repo,
75+
comment_id: existingComment.id,
76+
body,
77+
});
78+
} else {
79+
await github.rest.issues.createComment({
80+
owner: ownerContext,
81+
repo,
82+
issue_number: prNumber,
83+
body,
84+
});
85+
}
86+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
name: "PR - GHCR Image Link (Opened)"
6+
7+
on:
8+
pull_request_target:
9+
types: [opened, synchronize, reopened]
10+
11+
permissions:
12+
issues: write
13+
pull-requests: write
14+
15+
jobs:
16+
comment-pr:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
21+
22+
- name: Comment on the pull request
23+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
24+
with:
25+
script: |
26+
const script = require('./.github/scripts/pr-ghcr-image-comment.js');
27+
await script({ github, context, core });

0 commit comments

Comments
 (0)