Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-doctor.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/cli-version-checker.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/duplicate-code-detector.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/go-pattern-detector.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/issue-classifier.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/plan.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .github/workflows/poem-bot.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/semantic-function-refactor.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-claude.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-codex.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-copilot.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-detector.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/test-ollama-threat-detection.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/video-analyzer.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/workflow/add_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (c *Compiler) buildAddLabelsJob(data *WorkflowData, mainJobName string) (*J
StepID: "add_labels",
MainJobName: mainJobName,
CustomEnvVars: customEnvVars,
Script: addLabelsScript,
Script: getAddLabelsScript(),
Token: token,
})

Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/create_issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (c *Compiler) buildCreateOutputIssueJob(data *WorkflowData, mainJobName str
StepID: "create_issue",
MainJobName: mainJobName,
CustomEnvVars: customEnvVars,
Script: createIssueScript,
Script: getCreateIssueScript(),
Token: token,
})
steps = append(steps, scriptSteps...)
Expand Down
23 changes: 12 additions & 11 deletions pkg/workflow/create_issue_subissue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,58 +9,59 @@ import (

// TestCreateIssueSubissueFeature tests that the create_issue.js script includes subissue functionality
func TestCreateIssueSubissueFeature(t *testing.T) {
script := getCreateIssueScript()
// Test that the script contains the subissue detection logic
if !strings.Contains(createIssueScript, "context.payload?.issue?.number") {
if !strings.Contains(script, "context.payload?.issue?.number") {
t.Error("Expected create_issue.js to check for parent issue context")
}

// Test that the script modifies the body when in issue context
if !strings.Contains(createIssueScript, "Related to #${effectiveParentIssueNumber}") {
if !strings.Contains(script, "Related to #${effectiveParentIssueNumber}") {
t.Error("Expected create_issue.js to add parent issue reference to body")
}

// Test that the script supports explicit parent field
if !strings.Contains(createIssueScript, "createIssueItem.parent") {
if !strings.Contains(script, "createIssueItem.parent") {
t.Error("Expected create_issue.js to support explicit parent field")
}

// Test that the script uses effectiveParentIssueNumber
if !strings.Contains(createIssueScript, "effectiveParentIssueNumber") {
if !strings.Contains(script, "effectiveParentIssueNumber") {
t.Error("Expected create_issue.js to use effectiveParentIssueNumber variable")
}

// Test that the script includes GraphQL sub-issue linking
if !strings.Contains(createIssueScript, "addSubIssue") {
if !strings.Contains(script, "addSubIssue") {
t.Error("Expected create_issue.js to include addSubIssue GraphQL mutation")
}

// Test that the script calls github.graphql for sub-issue linking
if !strings.Contains(createIssueScript, "github.graphql(addSubIssueMutation") {
if !strings.Contains(script, "github.graphql(addSubIssueMutation") {
t.Error("Expected create_issue.js to call github.graphql for sub-issue linking")
}

// Test that the script fetches node IDs before linking
if !strings.Contains(createIssueScript, "getIssueNodeIdQuery") {
if !strings.Contains(script, "getIssueNodeIdQuery") {
t.Error("Expected create_issue.js to fetch issue node IDs before linking")
}

// Test that the script creates a comment on the parent issue
if !strings.Contains(createIssueScript, "github.rest.issues.createComment") {
if !strings.Contains(script, "github.rest.issues.createComment") {
t.Error("Expected create_issue.js to create comment on parent issue")
}

// Test that the script has proper error handling for sub-issue linking
if !strings.Contains(createIssueScript, "Warning: Could not link sub-issue to parent") {
if !strings.Contains(script, "Warning: Could not link sub-issue to parent") {
t.Error("Expected create_issue.js to have error handling for sub-issue linking")
}

// Test console logging for debugging
if !strings.Contains(createIssueScript, "Detected issue context, parent issue") {
if !strings.Contains(script, "Detected issue context, parent issue") {
t.Error("Expected create_issue.js to log when issue context is detected")
}

// Test that it logs successful sub-issue linking
if !strings.Contains(createIssueScript, "Successfully linked issue #") {
if !strings.Contains(script, "Successfully linked issue #") {
t.Error("Expected create_issue.js to log successful sub-issue linking")
}
}
Expand Down
56 changes: 49 additions & 7 deletions pkg/workflow/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import (
//go:embed js/create_pull_request.cjs
var createPullRequestScript string

//go:embed js/create_issue.cjs
var createIssueScript string

//go:embed js/create_agent_task.cjs
var createAgentTaskScript string

Expand All @@ -28,9 +25,6 @@ var createPRReviewCommentScript string
//go:embed js/create_code_scanning_alert.cjs
var createCodeScanningAlertScript string

//go:embed js/add_labels.cjs
var addLabelsScript string

//go:embed js/assign_issue.cjs
var assignIssueScript string

Expand Down Expand Up @@ -91,6 +85,9 @@ var notifyCommentErrorScript string
//go:embed js/sanitize.cjs
var sanitizeLibScript string

//go:embed js/sanitize_label_content.cjs
var sanitizeLabelContentScript string

//go:embed js/sanitize_workflow_name.cjs
var sanitizeWorkflowNameScript string

Expand All @@ -105,6 +102,12 @@ var computeTextScriptSource string
//go:embed js/sanitize_output.cjs
var sanitizeOutputScriptSource string

//go:embed js/create_issue.cjs
var createIssueScriptSource string

//go:embed js/add_labels.cjs
var addLabelsScriptSource string

//go:embed js/parse_firewall_logs.cjs
var parseFirewallLogsScriptSource string

Expand All @@ -119,6 +122,12 @@ var (
sanitizeOutputScript string
sanitizeOutputScriptOnce sync.Once

createIssueScript string
createIssueScriptOnce sync.Once

addLabelsScript string
addLabelsScriptOnce sync.Once

parseFirewallLogsScript string
parseFirewallLogsScriptOnce sync.Once
)
Expand Down Expand Up @@ -171,6 +180,38 @@ func getSanitizeOutputScript() string {
return sanitizeOutputScript
}

// getCreateIssueScript returns the bundled create_issue script
// Bundling is performed on first access and cached for subsequent calls
func getCreateIssueScript() string {
createIssueScriptOnce.Do(func() {
sources := GetJavaScriptSources()
bundled, err := BundleJavaScriptFromSources(createIssueScriptSource, sources, "")
if err != nil {
// If bundling fails, use the source as-is
createIssueScript = createIssueScriptSource
} else {
createIssueScript = bundled
}
})
return createIssueScript
}

// getAddLabelsScript returns the bundled add_labels script
// Bundling is performed on first access and cached for subsequent calls
func getAddLabelsScript() string {
addLabelsScriptOnce.Do(func() {
sources := GetJavaScriptSources()
bundled, err := BundleJavaScriptFromSources(addLabelsScriptSource, sources, "")
if err != nil {
// If bundling fails, use the source as-is
addLabelsScript = addLabelsScriptSource
} else {
addLabelsScript = bundled
}
})
return addLabelsScript
}

// getParseFirewallLogsScript returns the bundled parse_firewall_logs script
// Bundling is performed on first access and cached for subsequent calls
func getParseFirewallLogsScript() string {
Expand All @@ -191,7 +232,8 @@ func getParseFirewallLogsScript() string {
// The keys are the relative paths from the js directory
func GetJavaScriptSources() map[string]string {
return map[string]string{
"sanitize.cjs": sanitizeLibScript,
"sanitize.cjs": sanitizeLibScript,
"sanitize_label_content.cjs": sanitizeLabelContentScript,
"sanitize_workflow_name.cjs": sanitizeWorkflowNameScript,
}
}
Expand Down
15 changes: 1 addition & 14 deletions pkg/workflow/js/add_labels.cjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
// @ts-check
/// <reference types="@actions/github-script" />

function sanitizeLabelContent(content) {
if (!content || typeof content !== "string") {
return "";
}
let sanitized = content.trim();
sanitized = sanitized.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
sanitized = sanitized.replace(/\x1b\[[0-9;]*[mGKH]/g, "");
sanitized = sanitized.replace(
/(^|[^\w`])@([A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?(?:\/[A-Za-z0-9._-]+)?)/g,
(_m, p1, p2) => `${p1}\`@${p2}\``
);
sanitized = sanitized.replace(/[<>&'"]/g, "");
return sanitized.trim();
}
const { sanitizeLabelContent } = require("./sanitize_label_content.cjs");
async function main() {
const agentOutputFile = process.env.GH_AW_AGENT_OUTPUT;
if (!agentOutputFile) {
Expand Down
15 changes: 1 addition & 14 deletions pkg/workflow/js/create_issue.cjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
// @ts-check
/// <reference types="@actions/github-script" />

function sanitizeLabelContent(content) {
if (!content || typeof content !== "string") {
return "";
}
let sanitized = content.trim();
sanitized = sanitized.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
sanitized = sanitized.replace(/\x1b\[[0-9;]*[mGKH]/g, "");
sanitized = sanitized.replace(
/(^|[^\w`])@([A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?(?:\/[A-Za-z0-9._-]+)?)/g,
(_m, p1, p2) => `${p1}\`@${p2}\``
);
sanitized = sanitized.replace(/[<>&'"]/g, "");
return sanitized.trim();
}
const { sanitizeLabelContent } = require("./sanitize_label_content.cjs");

/**
* Generate footer with AI attribution and workflow installation instructions
Expand Down
Loading
Loading