diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml
index 4c235c401fa..b94b5dfa81d 100644
--- a/.github/workflows/archie.lock.yml
+++ b/.github/workflows/archie.lock.yml
@@ -851,6 +851,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -921,18 +933,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml
index ffdff5fed22..7066efaf51f 100644
--- a/.github/workflows/brave.lock.yml
+++ b/.github/workflows/brave.lock.yml
@@ -832,6 +832,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -902,18 +914,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml
index 30c63d9edc1..c6cf8bb2afd 100644
--- a/.github/workflows/ci-doctor.lock.yml
+++ b/.github/workflows/ci-doctor.lock.yml
@@ -258,6 +258,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -328,18 +340,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml
index d70d61bb583..8cff702a2b6 100644
--- a/.github/workflows/craft.lock.yml
+++ b/.github/workflows/craft.lock.yml
@@ -832,6 +832,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -902,18 +914,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/daily-perf-improver.lock.yml b/.github/workflows/daily-perf-improver.lock.yml
index a7a4b25ae74..664c2894285 100644
--- a/.github/workflows/daily-perf-improver.lock.yml
+++ b/.github/workflows/daily-perf-improver.lock.yml
@@ -270,6 +270,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -340,18 +352,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/daily-test-improver.lock.yml b/.github/workflows/daily-test-improver.lock.yml
index 5588d045da6..adba269c3fc 100644
--- a/.github/workflows/daily-test-improver.lock.yml
+++ b/.github/workflows/daily-test-improver.lock.yml
@@ -270,6 +270,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -340,18 +352,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml
index fdc374fb2c7..fae23f559f0 100644
--- a/.github/workflows/dev-hawk.lock.yml
+++ b/.github/workflows/dev-hawk.lock.yml
@@ -243,6 +243,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -313,18 +325,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml
index a53bb7ed63c..7b9f8fb5b12 100644
--- a/.github/workflows/grumpy-reviewer.lock.yml
+++ b/.github/workflows/grumpy-reviewer.lock.yml
@@ -838,6 +838,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -908,18 +920,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
@@ -4826,20 +4826,20 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function main() {
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
const result = loadAgentOutput();
if (!result.success) {
return;
diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml
index ff9b23ef6b3..05328f3b8cc 100644
--- a/.github/workflows/pdf-summary.lock.yml
+++ b/.github/workflows/pdf-summary.lock.yml
@@ -854,6 +854,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -924,18 +936,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml
index 86ab7391e83..2f115deef91 100644
--- a/.github/workflows/poem-bot.lock.yml
+++ b/.github/workflows/poem-bot.lock.yml
@@ -873,6 +873,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -943,18 +955,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
@@ -5622,20 +5622,20 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function main() {
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
const result = loadAgentOutput();
if (!result.success) {
return;
diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml
index 273c96d1d4d..fe24ec92674 100644
--- a/.github/workflows/pr-nitpick-reviewer.lock.yml
+++ b/.github/workflows/pr-nitpick-reviewer.lock.yml
@@ -634,6 +634,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -704,18 +716,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
@@ -5185,20 +5185,20 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function main() {
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
const result = loadAgentOutput();
if (!result.success) {
return;
diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml
index bc955ba1cf9..42928b78bba 100644
--- a/.github/workflows/q.lock.yml
+++ b/.github/workflows/q.lock.yml
@@ -879,6 +879,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -949,18 +961,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml
index e1c927a42bf..5fddb1101dd 100644
--- a/.github/workflows/scout.lock.yml
+++ b/.github/workflows/scout.lock.yml
@@ -880,6 +880,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -950,18 +962,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/smoke-detector.lock.yml b/.github/workflows/smoke-detector.lock.yml
index 610cd169c16..7aa74c0ec02 100644
--- a/.github/workflows/smoke-detector.lock.yml
+++ b/.github/workflows/smoke-detector.lock.yml
@@ -624,6 +624,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -694,18 +706,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml
index fd161a8337c..ac2f924d30e 100644
--- a/.github/workflows/technical-doc-writer.lock.yml
+++ b/.github/workflows/technical-doc-writer.lock.yml
@@ -258,6 +258,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -328,18 +340,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml
index 0db70d27cdc..7a934fb69ac 100644
--- a/.github/workflows/unbloat-docs.lock.yml
+++ b/.github/workflows/unbloat-docs.lock.yml
@@ -610,6 +610,18 @@ jobs:
footer += "\n";
return footer;
}
+ function getRepositoryUrl() {
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+ if (targetRepoSlug) {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ return context.payload.repository.html_url;
+ } else {
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+ }
async function commentOnDiscussion(github, owner, repo, discussionNumber, message, replyToId) {
const { repository } = await github.graphql(
`
@@ -680,18 +692,6 @@ jobs:
return;
}
core.info(`Found ${commentItems.length} add-comment item(s)`);
- function getRepositoryUrl() {
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
- if (targetRepoSlug) {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- return context.payload.repository.html_url;
- } else {
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
function getTargetNumber(item) {
return item.item_number;
}
diff --git a/pkg/workflow/js.go b/pkg/workflow/js.go
index c10d06b2780..9e7dce8439a 100644
--- a/pkg/workflow/js.go
+++ b/pkg/workflow/js.go
@@ -72,6 +72,12 @@ var isTruthyScript string
//go:embed js/update_activation_comment.cjs
var updateActivationCommentScript string
+//go:embed js/generate_footer.cjs
+var generateFooterScript string
+
+//go:embed js/get_repository_url.cjs
+var getRepositoryUrlScript string
+
// GetJavaScriptSources returns a map of all embedded JavaScript sources
// The keys are the relative paths from the js directory
func GetJavaScriptSources() map[string]string {
@@ -84,6 +90,8 @@ func GetJavaScriptSources() map[string]string {
"is_truthy.cjs": isTruthyScript,
"log_parser_bootstrap.cjs": logParserBootstrapScript,
"update_activation_comment.cjs": updateActivationCommentScript,
+ "generate_footer.cjs": generateFooterScript,
+ "get_repository_url.cjs": getRepositoryUrlScript,
}
}
diff --git a/pkg/workflow/js/add_comment.cjs b/pkg/workflow/js/add_comment.cjs
index 7e295efff3e..0f53789fb61 100644
--- a/pkg/workflow/js/add_comment.cjs
+++ b/pkg/workflow/js/add_comment.cjs
@@ -2,45 +2,8 @@
///
const { loadAgentOutput } = require("./load_agent_output.cjs");
-
-/**
- * Generate footer with AI attribution and workflow installation instructions
- * @param {string} workflowName - Name of the workflow
- * @param {string} runUrl - URL of the workflow run
- * @param {string} workflowSource - Source of the workflow (owner/repo/path@ref)
- * @param {string} workflowSourceURL - GitHub URL for the workflow source
- * @param {number|undefined} triggeringIssueNumber - Issue number that triggered this workflow
- * @param {number|undefined} triggeringPRNumber - Pull request number that triggered this workflow
- * @param {number|undefined} triggeringDiscussionNumber - Discussion number that triggered this workflow
- * @returns {string} Footer text
- */
-function generateFooter(
- workflowName,
- runUrl,
- workflowSource,
- workflowSourceURL,
- triggeringIssueNumber,
- triggeringPRNumber,
- triggeringDiscussionNumber
-) {
- let footer = `\n\n> AI generated by [${workflowName}](${runUrl})`;
-
- // Add reference to triggering issue/PR/discussion if available
- if (triggeringIssueNumber) {
- footer += ` for #${triggeringIssueNumber}`;
- } else if (triggeringPRNumber) {
- footer += ` for #${triggeringPRNumber}`;
- } else if (triggeringDiscussionNumber) {
- footer += ` for discussion #${triggeringDiscussionNumber}`;
- }
-
- if (workflowSource && workflowSourceURL) {
- footer += `\n>\n> To add this workflow in your repository, run \`gh aw add ${workflowSource}\`. See [usage guide](https://githubnext.github.io/gh-aw/tools/cli/).`;
- }
-
- footer += "\n";
- return footer;
-}
+const { generateFooter } = require("./generate_footer.cjs");
+const { getRepositoryUrl } = require("./get_repository_url.cjs");
/**
* Comment on a GitHub Discussion using GraphQL
@@ -138,25 +101,6 @@ async function main() {
core.info(`Found ${commentItems.length} add-comment item(s)`);
- // Helper function to get the repository URL for different purposes
- function getRepositoryUrl() {
- // For trial mode, use target repository for issue/PR URLs but execution context for action runs
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
-
- if (targetRepoSlug) {
- // Use target repository for issue/PR URLs in trial mode
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- // Use execution context repository (default behavior)
- return context.payload.repository.html_url;
- } else {
- // Final fallback for action runs when context repo is not available
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
-
// Helper function to get the target number (issue, discussion, or pull request)
function getTargetNumber(item) {
return item.item_number;
diff --git a/pkg/workflow/js/create_issue.cjs b/pkg/workflow/js/create_issue.cjs
index b087d0d2a23..0b44052ef54 100644
--- a/pkg/workflow/js/create_issue.cjs
+++ b/pkg/workflow/js/create_issue.cjs
@@ -4,45 +4,7 @@
const { sanitizeLabelContent } = require("./sanitize_label_content.cjs");
const { loadAgentOutput } = require("./load_agent_output.cjs");
const { generateStagedPreview } = require("./staged_preview.cjs");
-
-/**
- * Generate footer with AI attribution and workflow installation instructions
- * @param {string} workflowName - Name of the workflow
- * @param {string} runUrl - URL of the workflow run
- * @param {string} workflowSource - Source of the workflow (owner/repo/path@ref)
- * @param {string} workflowSourceURL - GitHub URL for the workflow source
- * @param {number|undefined} triggeringIssueNumber - Issue number that triggered this workflow
- * @param {number|undefined} triggeringPRNumber - Pull request number that triggered this workflow
- * @param {number|undefined} triggeringDiscussionNumber - Discussion number that triggered this workflow
- * @returns {string} Footer text
- */
-function generateFooter(
- workflowName,
- runUrl,
- workflowSource,
- workflowSourceURL,
- triggeringIssueNumber,
- triggeringPRNumber,
- triggeringDiscussionNumber
-) {
- let footer = `\n\n> AI generated by [${workflowName}](${runUrl})`;
-
- // Add reference to triggering issue/PR/discussion if available
- if (triggeringIssueNumber) {
- footer += ` for #${triggeringIssueNumber}`;
- } else if (triggeringPRNumber) {
- footer += ` for #${triggeringPRNumber}`;
- } else if (triggeringDiscussionNumber) {
- footer += ` for discussion #${triggeringDiscussionNumber}`;
- }
-
- if (workflowSource && workflowSourceURL) {
- footer += `\n>\n> To add this workflow in your repository, run \`gh aw add ${workflowSource}\`. See [usage guide](https://githubnext.github.io/gh-aw/tools/cli/).`;
- }
-
- footer += "\n";
- return footer;
-}
+const { generateFooter } = require("./generate_footer.cjs");
async function main() {
// Initialize outputs to empty strings to ensure they're always set
diff --git a/pkg/workflow/js/create_pr_review_comment.cjs b/pkg/workflow/js/create_pr_review_comment.cjs
index 54854677bab..3ef4818b66a 100644
--- a/pkg/workflow/js/create_pr_review_comment.cjs
+++ b/pkg/workflow/js/create_pr_review_comment.cjs
@@ -3,69 +3,13 @@
const { loadAgentOutput } = require("./load_agent_output.cjs");
const { generateStagedPreview } = require("./staged_preview.cjs");
-
-/**
- * Generate footer with AI attribution and workflow installation instructions
- * @param {string} workflowName - Name of the workflow
- * @param {string} runUrl - URL of the workflow run
- * @param {string} workflowSource - Source of the workflow (owner/repo/path@ref)
- * @param {string} workflowSourceURL - GitHub URL for the workflow source
- * @param {number|undefined} triggeringIssueNumber - Issue number that triggered this workflow
- * @param {number|undefined} triggeringPRNumber - Pull request number that triggered this workflow
- * @param {number|undefined} triggeringDiscussionNumber - Discussion number that triggered this workflow
- * @returns {string} Footer text
- */
-function generateFooter(
- workflowName,
- runUrl,
- workflowSource,
- workflowSourceURL,
- triggeringIssueNumber,
- triggeringPRNumber,
- triggeringDiscussionNumber
-) {
- let footer = `\n\n> AI generated by [${workflowName}](${runUrl})`;
-
- // Add reference to triggering issue/PR/discussion if available
- if (triggeringIssueNumber) {
- footer += ` for #${triggeringIssueNumber}`;
- } else if (triggeringPRNumber) {
- footer += ` for #${triggeringPRNumber}`;
- } else if (triggeringDiscussionNumber) {
- footer += ` for discussion #${triggeringDiscussionNumber}`;
- }
-
- if (workflowSource && workflowSourceURL) {
- footer += `\n>\n> To add this workflow in your repository, run \`gh aw add ${workflowSource}\`. See [usage guide](https://githubnext.github.io/gh-aw/tools/cli/).`;
- }
-
- footer += "\n";
- return footer;
-}
+const { generateFooter } = require("./generate_footer.cjs");
+const { getRepositoryUrl } = require("./get_repository_url.cjs");
async function main() {
// Check if we're in staged mode
const isStaged = process.env.GH_AW_SAFE_OUTPUTS_STAGED === "true";
- // Helper function to get the repository URL for different purposes
- function getRepositoryUrl() {
- // For trial mode, use target repository for issue/PR URLs but execution context for action runs
- const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
-
- if (targetRepoSlug) {
- // Use target repository for issue/PR URLs in trial mode
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${targetRepoSlug}`;
- } else if (context.payload.repository) {
- // Use execution context repository (default behavior)
- return context.payload.repository.html_url;
- } else {
- // Final fallback for action runs when context repo is not available
- const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
- return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
- }
- }
-
const result = loadAgentOutput();
if (!result.success) {
return;
diff --git a/pkg/workflow/js/generate_footer.cjs b/pkg/workflow/js/generate_footer.cjs
new file mode 100644
index 00000000000..f1bb21ebde4
--- /dev/null
+++ b/pkg/workflow/js/generate_footer.cjs
@@ -0,0 +1,45 @@
+// @ts-check
+///
+
+/**
+ * Generate footer with AI attribution and workflow installation instructions
+ * @param {string} workflowName - Name of the workflow
+ * @param {string} runUrl - URL of the workflow run
+ * @param {string} workflowSource - Source of the workflow (owner/repo/path@ref)
+ * @param {string} workflowSourceURL - GitHub URL for the workflow source
+ * @param {number|undefined} triggeringIssueNumber - Issue number that triggered this workflow
+ * @param {number|undefined} triggeringPRNumber - Pull request number that triggered this workflow
+ * @param {number|undefined} triggeringDiscussionNumber - Discussion number that triggered this workflow
+ * @returns {string} Footer text
+ */
+function generateFooter(
+ workflowName,
+ runUrl,
+ workflowSource,
+ workflowSourceURL,
+ triggeringIssueNumber,
+ triggeringPRNumber,
+ triggeringDiscussionNumber
+) {
+ let footer = `\n\n> AI generated by [${workflowName}](${runUrl})`;
+
+ // Add reference to triggering issue/PR/discussion if available
+ if (triggeringIssueNumber) {
+ footer += ` for #${triggeringIssueNumber}`;
+ } else if (triggeringPRNumber) {
+ footer += ` for #${triggeringPRNumber}`;
+ } else if (triggeringDiscussionNumber) {
+ footer += ` for discussion #${triggeringDiscussionNumber}`;
+ }
+
+ if (workflowSource && workflowSourceURL) {
+ footer += `\n>\n> To add this workflow in your repository, run \`gh aw add ${workflowSource}\`. See [usage guide](https://githubnext.github.io/gh-aw/tools/cli/).`;
+ }
+
+ footer += "\n";
+ return footer;
+}
+
+module.exports = {
+ generateFooter,
+};
diff --git a/pkg/workflow/js/generate_footer.test.cjs b/pkg/workflow/js/generate_footer.test.cjs
new file mode 100644
index 00000000000..18abe7e1022
--- /dev/null
+++ b/pkg/workflow/js/generate_footer.test.cjs
@@ -0,0 +1,168 @@
+import { describe, it, expect, beforeEach, vi } from "vitest";
+
+// Mock the global objects that GitHub Actions provides
+const mockCore = {
+ debug: vi.fn(),
+ info: vi.fn(),
+ warning: vi.fn(),
+ error: vi.fn(),
+ setFailed: vi.fn(),
+ setOutput: vi.fn(),
+ summary: {
+ addRaw: vi.fn().mockReturnThis(),
+ write: vi.fn().mockResolvedValue(),
+ },
+};
+
+const mockContext = {
+ runId: 12345,
+ repo: {
+ owner: "testowner",
+ repo: "testrepo",
+ },
+ payload: {
+ repository: {
+ html_url: "https://github.com/testowner/testrepo",
+ },
+ },
+};
+
+// Set up global mocks before importing the module
+global.core = mockCore;
+global.context = mockContext;
+
+describe("generate_footer.cjs", () => {
+ let generateFooter;
+
+ beforeEach(async () => {
+ // Reset mocks
+ vi.clearAllMocks();
+
+ // Dynamic import to get fresh module state
+ const module = await import("./generate_footer.cjs");
+ generateFooter = module.generateFooter;
+ });
+
+ describe("generateFooter", () => {
+ it("should generate basic footer with workflow name and run URL", () => {
+ const result = generateFooter(
+ "Test Workflow",
+ "https://github.com/test/repo/actions/runs/123",
+ "",
+ "",
+ undefined,
+ undefined,
+ undefined
+ );
+
+ expect(result).toContain("> AI generated by [Test Workflow](https://github.com/test/repo/actions/runs/123)");
+ expect(result).not.toContain("for #");
+ expect(result).not.toContain("gh aw add");
+ });
+
+ it("should include issue number reference when provided", () => {
+ const result = generateFooter("Test Workflow", "https://github.com/test/repo/actions/runs/123", "", "", 42, undefined, undefined);
+
+ expect(result).toContain("> AI generated by [Test Workflow](https://github.com/test/repo/actions/runs/123) for #42");
+ });
+
+ it("should include PR number reference when provided", () => {
+ const result = generateFooter("Test Workflow", "https://github.com/test/repo/actions/runs/123", "", "", undefined, 99, undefined);
+
+ expect(result).toContain("> AI generated by [Test Workflow](https://github.com/test/repo/actions/runs/123) for #99");
+ });
+
+ it("should include discussion number reference when provided", () => {
+ const result = generateFooter("Test Workflow", "https://github.com/test/repo/actions/runs/123", "", "", undefined, undefined, 7);
+
+ expect(result).toContain("> AI generated by [Test Workflow](https://github.com/test/repo/actions/runs/123) for discussion #7");
+ });
+
+ it("should prioritize issue number over PR number", () => {
+ const result = generateFooter("Test Workflow", "https://github.com/test/repo/actions/runs/123", "", "", 42, 99, undefined);
+
+ expect(result).toContain("for #42");
+ expect(result).not.toContain("for #99");
+ });
+
+ it("should prioritize PR number over discussion number", () => {
+ const result = generateFooter("Test Workflow", "https://github.com/test/repo/actions/runs/123", "", "", undefined, 99, 7);
+
+ expect(result).toContain("for #99");
+ expect(result).not.toContain("for discussion #7");
+ });
+
+ it("should include workflow installation instructions when source is provided", () => {
+ const result = generateFooter(
+ "Test Workflow",
+ "https://github.com/test/repo/actions/runs/123",
+ "owner/repo/workflow.md@main",
+ "https://github.com/owner/repo/blob/main/workflow.md",
+ undefined,
+ undefined,
+ undefined
+ );
+
+ expect(result).toContain("gh aw add owner/repo/workflow.md@main");
+ expect(result).toContain("See [usage guide](https://githubnext.github.io/gh-aw/tools/cli/)");
+ });
+
+ it("should not include installation instructions when source is empty", () => {
+ const result = generateFooter(
+ "Test Workflow",
+ "https://github.com/test/repo/actions/runs/123",
+ "",
+ "",
+ undefined,
+ undefined,
+ undefined
+ );
+
+ expect(result).not.toContain("gh aw add");
+ });
+
+ it("should include both issue reference and installation instructions", () => {
+ const result = generateFooter(
+ "Test Workflow",
+ "https://github.com/test/repo/actions/runs/123",
+ "owner/repo/workflow.md@main",
+ "https://github.com/owner/repo/blob/main/workflow.md",
+ 42,
+ undefined,
+ undefined
+ );
+
+ expect(result).toContain("for #42");
+ expect(result).toContain("gh aw add owner/repo/workflow.md@main");
+ });
+
+ it("should start and end with newlines", () => {
+ const result = generateFooter(
+ "Test Workflow",
+ "https://github.com/test/repo/actions/runs/123",
+ "",
+ "",
+ undefined,
+ undefined,
+ undefined
+ );
+
+ expect(result).toMatch(/^\n\n/);
+ expect(result).toMatch(/\n$/);
+ });
+
+ it("should handle special characters in workflow name", () => {
+ const result = generateFooter(
+ "Test Workflow (v2) [beta]",
+ "https://github.com/test/repo/actions/runs/123",
+ "",
+ "",
+ undefined,
+ undefined,
+ undefined
+ );
+
+ expect(result).toContain("> AI generated by [Test Workflow (v2) [beta]](https://github.com/test/repo/actions/runs/123)");
+ });
+ });
+});
diff --git a/pkg/workflow/js/get_repository_url.cjs b/pkg/workflow/js/get_repository_url.cjs
new file mode 100644
index 00000000000..d9f5556b478
--- /dev/null
+++ b/pkg/workflow/js/get_repository_url.cjs
@@ -0,0 +1,29 @@
+// @ts-check
+///
+
+/**
+ * Get the repository URL for different purposes
+ * This helper handles trial mode where target repository URLs are different from execution context
+ * @returns {string} Repository URL
+ */
+function getRepositoryUrl() {
+ // For trial mode, use target repository for issue/PR URLs but execution context for action runs
+ const targetRepoSlug = process.env.GH_AW_TARGET_REPO_SLUG;
+
+ if (targetRepoSlug) {
+ // Use target repository for issue/PR URLs in trial mode
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${targetRepoSlug}`;
+ } else if (context.payload.repository?.html_url) {
+ // Use execution context repository (default behavior)
+ return context.payload.repository.html_url;
+ } else {
+ // Final fallback for action runs when context repo is not available
+ const githubServer = process.env.GITHUB_SERVER_URL || "https://github.com";
+ return `${githubServer}/${context.repo.owner}/${context.repo.repo}`;
+ }
+}
+
+module.exports = {
+ getRepositoryUrl,
+};
diff --git a/pkg/workflow/js/get_repository_url.test.cjs b/pkg/workflow/js/get_repository_url.test.cjs
new file mode 100644
index 00000000000..ab5bf9880c3
--- /dev/null
+++ b/pkg/workflow/js/get_repository_url.test.cjs
@@ -0,0 +1,118 @@
+import { describe, it, expect, beforeEach, vi } from "vitest";
+
+// Mock the global objects that GitHub Actions provides
+const mockCore = {
+ debug: vi.fn(),
+ info: vi.fn(),
+ warning: vi.fn(),
+ error: vi.fn(),
+ setFailed: vi.fn(),
+ setOutput: vi.fn(),
+ summary: {
+ addRaw: vi.fn().mockReturnThis(),
+ write: vi.fn().mockResolvedValue(),
+ },
+};
+
+const mockContext = {
+ runId: 12345,
+ repo: {
+ owner: "testowner",
+ repo: "testrepo",
+ },
+ payload: {
+ repository: {
+ html_url: "https://github.com/testowner/testrepo",
+ },
+ },
+};
+
+// Set up global mocks before importing the module
+global.core = mockCore;
+global.context = mockContext;
+
+describe("get_repository_url.cjs", () => {
+ let getRepositoryUrl;
+
+ beforeEach(async () => {
+ // Reset mocks
+ vi.clearAllMocks();
+
+ // Reset environment variables
+ delete process.env.GH_AW_TARGET_REPO_SLUG;
+ delete process.env.GITHUB_SERVER_URL;
+
+ // Reset context
+ global.context = {
+ runId: 12345,
+ repo: {
+ owner: "testowner",
+ repo: "testrepo",
+ },
+ payload: {
+ repository: {
+ html_url: "https://github.com/testowner/testrepo",
+ },
+ },
+ };
+
+ // Dynamic import to get fresh module state
+ const module = await import("./get_repository_url.cjs");
+ getRepositoryUrl = module.getRepositoryUrl;
+ });
+
+ describe("getRepositoryUrl", () => {
+ it("should return repository URL from context payload", () => {
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.com/testowner/testrepo");
+ });
+
+ it("should return target repository URL in trial mode", () => {
+ process.env.GH_AW_TARGET_REPO_SLUG = "targetowner/targetrepo";
+
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.com/targetowner/targetrepo");
+ });
+
+ it("should use custom GitHub server URL in trial mode", () => {
+ process.env.GH_AW_TARGET_REPO_SLUG = "targetowner/targetrepo";
+ process.env.GITHUB_SERVER_URL = "https://github.enterprise.com";
+
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.enterprise.com/targetowner/targetrepo");
+ });
+
+ it("should fallback to context repo when payload is missing", () => {
+ global.context.payload = {};
+
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.com/testowner/testrepo");
+ });
+
+ it("should use custom GitHub server URL in fallback", () => {
+ global.context.payload = {};
+ process.env.GITHUB_SERVER_URL = "https://github.enterprise.com";
+
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.enterprise.com/testowner/testrepo");
+ });
+
+ it("should prioritize target repo over payload in trial mode", () => {
+ process.env.GH_AW_TARGET_REPO_SLUG = "targetowner/targetrepo";
+ global.context.payload = {
+ repository: {
+ html_url: "https://github.com/originalowner/originalrepo",
+ },
+ };
+
+ const result = getRepositoryUrl();
+
+ expect(result).toBe("https://github.com/targetowner/targetrepo");
+ });
+ });
+});