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
6 changes: 3 additions & 3 deletions .github/workflows/dependabot-burner.lock.yml

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

4 changes: 3 additions & 1 deletion .github/workflows/dependabot-burner.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ permissions:
imports:
- shared/campaign.md

project: https://github.com/orgs/githubnext/projects/144
safe-outputs:
update-project:
project: https://github.com/orgs/githubnext/projects/144
---

# Dependabot Burner
Expand Down
89 changes: 3 additions & 86 deletions .github/workflows/security-alert-burndown.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/security-alert-burndown.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ safe-outputs:
github-token: ${{ secrets.GH_AW_AGENT_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
update-project:
max: 100
project: https://github.com/orgs/githubnext/projects/144
create-issue:
expires: 2d
max: 1
title-prefix: "[campaign]"
assignees: copilot
project: https://github.com/orgs/githubnext/projects/144
---

# Security Alert Burndown
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/smoke-project.lock.yml

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

3 changes: 2 additions & 1 deletion .github/workflows/smoke-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ permissions:
actions: read
name: Smoke Project
engine: copilot
project: "https://github.com/orgs/github-agentic-workflows/projects/1"
imports:
- shared/gh.md
- shared/reporting.md
Expand All @@ -41,6 +40,7 @@ safe-outputs:
allowed: [smoke-project]
update-project:
max: 20
project: "https://github.com/orgs/github-agentic-workflows/projects/1"
views:
- name: "Smoke Test Board"
layout: board
Expand All @@ -50,6 +50,7 @@ safe-outputs:
github-token: ${{ secrets.SMOKE_PROJECT_GITHUB_TOKEN }}
create-project-status-update:
max: 5
project: "https://github.com/orgs/github-agentic-workflows/projects/1"
github-token: ${{ secrets.SMOKE_PROJECT_GITHUB_TOKEN }}
messages:
append-only-comments: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-project-url-default.lock.yml

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

26 changes: 14 additions & 12 deletions .github/workflows/test-project-url-default.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ engine: copilot
on:
workflow_dispatch:

project: "https://github.com/orgs/<ORG>/projects/<NUMBER>"

safe-outputs:
update-project:
max: 5
project: "https://github.com/orgs/<ORG>/projects/<NUMBER>"
create-project-status-update:
max: 1
project: "https://github.com/orgs/<ORG>/projects/<NUMBER>"
---

# Test Default Project URL

This workflow demonstrates the new `GH_AW_PROJECT_URL` environment variable feature.
This workflow demonstrates the `project:` field within safe-outputs configuration.

When the `project` field is configured in the frontmatter, safe output entries like
`update-project` and `create-project-status-update` will automatically use this project
URL as a default when the message doesn't specify a project field.
When the `project` field is configured in safe-outputs like `update-project` or
`create-project-status-update`, the safe output handler will use this URL as the
default project when processing messages.

## Test Cases

1. **Default project URL from frontmatter**: Safe output messages without a `project` field
will use the URL from the frontmatter configuration.
1. **Default project URL from safe-outputs config**: Safe output messages without a
`project` field will use the URL from the safe-outputs configuration.

2. **Override with explicit project**: If a safe output message includes a `project` field,
it takes precedence over the frontmatter default.
2. **Override with explicit project**: If a safe output message includes a `project`
field, it takes precedence over the configured default.

## Example Safe Outputs

Expand All @@ -42,9 +42,11 @@ URL as a default when the message doesn't specify a project field.
}
```

This will automatically use `https://github.com/orgs/<ORG>/projects/<NUMBER>` from the frontmatter.
This will automatically use `https://github.com/orgs/<ORG>/projects/<NUMBER>` from the
safe-outputs configuration.

Important: this is a placeholder. Replace it with a real GitHub Projects v2 URL before running the workflow.
Important: this is a placeholder. Replace it with a real GitHub Projects v2 URL before
running the workflow.

```json
{
Expand Down
9 changes: 5 additions & 4 deletions actions/setup/js/create_project_status_update.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -309,18 +309,19 @@ async function main(config = {}, githubClient = null) {

const output = message;

// Get default project URL from environment if available
// Get configured project URL from environment
// This is set from the safe-outputs configuration where project is required
const defaultProjectUrl = process.env.GH_AW_PROJECT_URL || "";

// Validate project field - can use default from frontmatter if available
// Determine effective project URL: output.project takes precedence, otherwise use configured URL
let effectiveProjectUrl = output.project;

if (!effectiveProjectUrl || typeof effectiveProjectUrl !== "string" || effectiveProjectUrl.trim() === "") {
if (defaultProjectUrl) {
core.info(`Using default project URL from frontmatter: ${defaultProjectUrl}`);
core.info(`Using project URL from safe-outputs configuration: ${defaultProjectUrl}`);
effectiveProjectUrl = defaultProjectUrl;
} else {
core.error("Missing required field: project (GitHub project URL)");
core.error('Missing required "project" field. Configure it in safe-outputs: create-project-status-update: {project: "https://github.com/orgs/myorg/projects/42"}');
return {
success: false,
error: "Missing required field: project",
Expand Down
4 changes: 2 additions & 2 deletions actions/setup/js/create_project_status_update.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ describe("create_project_status_update", () => {

expect(result.success).toBe(true);
expect(result.status_update_id).toBe("PVTSU_test456");
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("Using default project URL from frontmatter"));
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("Using project URL from safe-outputs configuration"));

// Cleanup
delete process.env.GH_AW_PROJECT_URL;
Expand Down Expand Up @@ -579,7 +579,7 @@ describe("create_project_status_update", () => {
expect(result.success).toBe(true);
expect(result.status_update_id).toBe("PVTSU_test789");
// Should not use default from environment
expect(mockCore.info).not.toHaveBeenCalledWith(expect.stringContaining("Using default project URL from frontmatter"));
expect(mockCore.info).not.toHaveBeenCalledWith(expect.stringContaining("Using project URL from safe-outputs configuration"));

// Cleanup
delete process.env.GH_AW_PROJECT_URL;
Expand Down
11 changes: 5 additions & 6 deletions actions/setup/js/update_project.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,20 +1042,19 @@ async function main(config = {}) {
}

try {
// Get default project URL from environment if available
// Get configured project URL from environment
// This is set from the safe-outputs configuration where project is required
const defaultProjectUrl = process.env.GH_AW_PROJECT_URL || "";

// Validate project field - can use default from frontmatter if available
// Determine effective project URL: message.project takes precedence, otherwise use configured URL
let effectiveProjectUrl = message.project;

// If no project field in message, try to use default from frontmatter
if (!effectiveProjectUrl || typeof effectiveProjectUrl !== "string" || effectiveProjectUrl.trim() === "") {
if (defaultProjectUrl) {
core.info(`Using default project URL from frontmatter: ${defaultProjectUrl}`);
core.info(`Using project URL from safe-outputs configuration: ${defaultProjectUrl}`);
effectiveProjectUrl = defaultProjectUrl;
} else {
const errorMsg =
'Missing required "project" field in update_project message. The "project" field must be a full GitHub project URL (e.g., "https://github.com/orgs/myorg/projects/42"), or configure a default project URL in the workflow frontmatter.';
const errorMsg = 'Missing required "project" field. Either include "project" in the message, or configure it in safe-outputs: update-project: {project: "https://github.com/orgs/myorg/projects/42"}';
core.error(errorMsg);

// Provide helpful context based on content_type
Expand Down
2 changes: 1 addition & 1 deletion actions/setup/js/update_project.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,7 @@ describe("updateProject", () => {
const result = await messageHandler(messageWithoutProject, new Map());

expect(result.success).toBe(true);
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("Using default project URL from frontmatter"));
expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("Using project URL from safe-outputs configuration"));
expect(getOutput("item-id")).toBe("draft-item-default");

// Cleanup
Expand Down
Loading
Loading