diff --git a/.changeset/patch-unify-project-safe-output-handlers.md b/.changeset/patch-unify-project-safe-output-handlers.md new file mode 100644 index 0000000000..2b5da0b330 --- /dev/null +++ b/.changeset/patch-unify-project-safe-output-handlers.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Moved the update-project and create-project-status-update safe-output configs into the unified handler manager so workflows no longer run a separate project handler step for those types. diff --git a/.github/workflows/dependabot-burner.lock.yml b/.github/workflows/dependabot-burner.lock.yml index a10273b5f9..908e6e78a3 100644 --- a/.github/workflows/dependabot-burner.lock.yml +++ b/.github/workflows/dependabot-burner.lock.yml @@ -1263,8 +1263,6 @@ jobs: GH_AW_WORKFLOW_ID: "dependabot-burner" GH_AW_WORKFLOW_NAME: "Dependabot Burner" outputs: - process_project_safe_outputs_processed_count: ${{ steps.process_project_safe_outputs.outputs.processed_count }} - process_project_safe_outputs_temporary_project_map: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: @@ -1290,28 +1288,13 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs/ find "/tmp/gh-aw/safeoutputs/" -type f -print echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Project-Related Safe Outputs - id: process_project_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG: "{\"create_project_status_update\":{\"max\":1},\"update_project\":{\"max\":100}}" - GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - GH_AW_PROJECT_URL: "https://github.com/orgs/githubnext/projects/144" - with: - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_project_handler_manager.cjs'); - await main(); - name: Process Safe Outputs id: process_safe_outputs uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} GH_AW_TEMPORARY_PROJECT_MAP: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"expires\":48,\"max\":5},\"missing_data\":{},\"missing_tool\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"expires\":48,\"max\":5},\"create_project_status_update\":{\"max\":1,\"project\":\"https://github.com/orgs/githubnext/projects/144\"},\"missing_data\":{},\"missing_tool\":{},\"update_project\":{\"max\":100,\"project\":\"https://github.com/orgs/githubnext/projects/144\"}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/security-alert-burndown.lock.yml b/.github/workflows/security-alert-burndown.lock.yml index 47ee6af4f1..53c3461917 100644 --- a/.github/workflows/security-alert-burndown.lock.yml +++ b/.github/workflows/security-alert-burndown.lock.yml @@ -1225,8 +1225,6 @@ jobs: GH_AW_WORKFLOW_ID: "security-alert-burndown" GH_AW_WORKFLOW_NAME: "Security Alert Burndown" outputs: - process_project_safe_outputs_processed_count: ${{ steps.process_project_safe_outputs.outputs.processed_count }} - process_project_safe_outputs_temporary_project_map: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: @@ -1252,29 +1250,13 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs/ find "/tmp/gh-aw/safeoutputs/" -type f -print echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Project-Related Safe Outputs - id: process_project_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG: "{\"create_project_status_update\":{\"max\":1},\"update_project\":{\"max\":100}}" - GH_AW_ASSIGN_COPILOT: "true" - GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - GH_AW_PROJECT_URL: "https://github.com/orgs/githubnext/projects/144" - with: - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_project_handler_manager.cjs'); - await main(); - name: Process Safe Outputs id: process_safe_outputs uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} GH_AW_TEMPORARY_PROJECT_MAP: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"assignees\":[\"copilot\"],\"max\":1},\"missing_data\":{},\"missing_tool\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"assignees\":[\"copilot\"],\"max\":1},\"create_project_status_update\":{\"max\":1,\"project\":\"https://github.com/orgs/githubnext/projects/144\"},\"missing_data\":{},\"missing_tool\":{},\"update_project\":{\"max\":100,\"project\":\"https://github.com/orgs/githubnext/projects/144\"}}" GH_AW_ASSIGN_COPILOT: "true" with: github-token: ${{ secrets.GH_AW_AGENT_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 1927f88a67..293c27fb83 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -2108,8 +2108,6 @@ jobs: GH_AW_WORKFLOW_ID: "smoke-copilot" GH_AW_WORKFLOW_NAME: "Smoke Copilot" outputs: - process_project_safe_outputs_processed_count: ${{ steps.process_project_safe_outputs.outputs.processed_count }} - process_project_safe_outputs_temporary_project_map: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: @@ -2135,28 +2133,13 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs/ find "/tmp/gh-aw/safeoutputs/" -type f -print echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Project-Related Safe Outputs - id: process_project_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG: "{\"create_project_status_update\":{\"max\":5},\"update_project\":{\"max\":20,\"views\":[{\"name\":\"Smoke Test Board\",\"layout\":\"board\",\"filter\":\"is:open\"},{\"name\":\"Smoke Test Table\",\"layout\":\"table\"}]}}" - GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - GH_AW_PROJECT_URL: "https://github.com/orgs/nonexistent-test-org-12345/projects/99999" - with: - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_project_handler_manager.cjs'); - await main(); - name: Process Safe Outputs id: process_safe_outputs uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} GH_AW_TEMPORARY_PROJECT_MAP: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-copilot\"]},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"group\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"remove_labels\":{\"allowed\":[\"smoke\"]}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"add_labels\":{\"allowed\":[\"smoke-copilot\"]},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"group\":true,\"max\":1},\"create_project_status_update\":{\"max\":5,\"project\":\"https://github.com/orgs/nonexistent-test-org-12345/projects/99999\"},\"missing_data\":{},\"missing_tool\":{},\"remove_labels\":{\"allowed\":[\"smoke\"]},\"update_project\":{\"max\":20,\"project\":\"https://github.com/orgs/nonexistent-test-org-12345/projects/99999\",\"views\":[{\"name\":\"Smoke Test Board\",\"layout\":\"board\",\"filter\":\"is:open\"},{\"name\":\"Smoke Test Table\",\"layout\":\"table\"}]}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/test-project-url-default.lock.yml b/.github/workflows/test-project-url-default.lock.yml index 2c683955c8..a629dea6cf 100644 --- a/.github/workflows/test-project-url-default.lock.yml +++ b/.github/workflows/test-project-url-default.lock.yml @@ -1146,8 +1146,6 @@ jobs: GH_AW_WORKFLOW_ID: "test-project-url-default" GH_AW_WORKFLOW_NAME: "Test Project URL Default" outputs: - process_project_safe_outputs_processed_count: ${{ steps.process_project_safe_outputs.outputs.processed_count }} - process_project_safe_outputs_temporary_project_map: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: @@ -1173,28 +1171,13 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs/ find "/tmp/gh-aw/safeoutputs/" -type f -print echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV" - - name: Process Project-Related Safe Outputs - id: process_project_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 - env: - GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} - GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG: "{\"create_project_status_update\":{\"max\":1},\"update_project\":{\"max\":5}}" - GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - GH_AW_PROJECT_URL: "https://github.com/orgs//projects/" - with: - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('/opt/gh-aw/actions/safe_output_project_handler_manager.cjs'); - await main(); - name: Process Safe Outputs id: process_safe_outputs uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }} GH_AW_TEMPORARY_PROJECT_MAP: ${{ steps.process_project_safe_outputs.outputs.temporary_project_map }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"missing_data\":{},\"missing_tool\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_project_status_update\":{\"max\":1,\"project\":\"https://github.com/orgs/\\u003cORG\\u003e/projects/\\u003cNUMBER\\u003e\"},\"missing_data\":{},\"missing_tool\":{},\"update_project\":{\"max\":5,\"project\":\"https://github.com/orgs/\\u003cORG\\u003e/projects/\\u003cNUMBER\\u003e\"}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/actions/setup/js/safe_output_project_handler_manager.cjs b/actions/setup/js/safe_output_project_handler_manager.cjs index 32a0fcc140..3bfabb4e78 100644 --- a/actions/setup/js/safe_output_project_handler_manager.cjs +++ b/actions/setup/js/safe_output_project_handler_manager.cjs @@ -7,7 +7,10 @@ * This module manages the dispatch of project-related safe output messages to dedicated handlers. * It handles safe output types that require GH_AW_PROJECT_GITHUB_TOKEN: * - create_project - * - create_project_status_update + * - copy_project + * + * Note: update_project and create_project_status_update are now handled by the unified + * handler manager (safe_output_unified_handler_manager.cjs) and should NOT be processed here. * * These types are separated from the main handler manager because they require a different * GitHub token (GH_AW_PROJECT_GITHUB_TOKEN) than other safe output types. @@ -23,11 +26,12 @@ const { loadCustomSafeOutputJobTypes } = require("./safe_output_helpers.cjs"); * Handler map configuration for project-related safe outputs * Maps safe output types to their handler module file paths * All these types require GH_AW_PROJECT_GITHUB_TOKEN + * + * Note: update_project and create_project_status_update are intentionally excluded + * from this map as they are now handled by the unified handler manager. */ const PROJECT_HANDLER_MAP = { create_project: "./create_project.cjs", - create_project_status_update: "./create_project_status_update.cjs", - update_project: "./update_project.cjs", copy_project: "./copy_project.cjs", }; diff --git a/pkg/workflow/compiler_safe_outputs_config.go b/pkg/workflow/compiler_safe_outputs_config.go index 4525d73331..bdc8b5ef72 100644 --- a/pkg/workflow/compiler_safe_outputs_config.go +++ b/pkg/workflow/compiler_safe_outputs_config.go @@ -422,20 +422,17 @@ var handlerRegistry = map[string]handlerBuilder{ AddIfNotEmpty("github-token", c.GitHubToken). Build() }, -} - -// projectHandlerRegistry maps project handler names to their builder functions -var projectHandlerRegistry = map[string]handlerBuilder{ - "create_project": func(cfg *SafeOutputsConfig) map[string]any { - if cfg.CreateProjects == nil { + // Note: update_project and create_project_status_update are handled by the unified handler, + // not the separate project handler manager, so they are included in this registry. + "update_project": func(cfg *SafeOutputsConfig) map[string]any { + if cfg.UpdateProjects == nil { return nil } - c := cfg.CreateProjects + c := cfg.UpdateProjects builder := newHandlerConfigBuilder(). AddIfPositive("max", c.Max). - AddIfNotEmpty("target_owner", c.TargetOwner). - AddIfNotEmpty("title_prefix", c.TitlePrefix). - AddIfNotEmpty("github-token", c.GitHubToken) + AddIfNotEmpty("github-token", c.GitHubToken). + AddIfNotEmpty("project", c.Project) if len(c.Views) > 0 { builder.AddDefault("views", c.Views) } @@ -452,15 +449,25 @@ var projectHandlerRegistry = map[string]handlerBuilder{ return newHandlerConfigBuilder(). AddIfPositive("max", c.Max). AddIfNotEmpty("github-token", c.GitHubToken). + AddIfNotEmpty("project", c.Project). Build() }, - "update_project": func(cfg *SafeOutputsConfig) map[string]any { - if cfg.UpdateProjects == nil { +} + +// projectHandlerRegistry maps project handler names to their builder functions +// Note: As of recent changes, only create_project and copy_project are in this registry. +// update_project and create_project_status_update have been moved to the main handlerRegistry +// as they are now handled by the unified handler. +var projectHandlerRegistry = map[string]handlerBuilder{ + "create_project": func(cfg *SafeOutputsConfig) map[string]any { + if cfg.CreateProjects == nil { return nil } - c := cfg.UpdateProjects + c := cfg.CreateProjects builder := newHandlerConfigBuilder(). AddIfPositive("max", c.Max). + AddIfNotEmpty("target_owner", c.TargetOwner). + AddIfNotEmpty("title_prefix", c.TitlePrefix). AddIfNotEmpty("github-token", c.GitHubToken) if len(c.Views) > 0 { builder.AddDefault("views", c.Views) @@ -523,8 +530,10 @@ func (c *Compiler) addHandlerManagerConfigEnvVar(steps *[]string, data *Workflow } // addProjectHandlerManagerConfigEnvVar adds the GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG environment variable -// containing JSON configuration for project-related safe output handlers (create_project, create_project_status_update). +// containing JSON configuration for project-related safe output handlers (create_project, copy_project). // These handlers require GH_AW_PROJECT_GITHUB_TOKEN and are processed separately from the main handler manager. +// Note: update_project and create_project_status_update are now handled by the unified handler and are +// NOT included in this config. func (c *Compiler) addProjectHandlerManagerConfigEnvVar(steps *[]string, data *WorkflowData) { if data.SafeOutputs == nil { compilerSafeOutputsConfigLog.Print("No safe-outputs configuration, skipping project handler config") diff --git a/pkg/workflow/compiler_safe_outputs_job.go b/pkg/workflow/compiler_safe_outputs_job.go index 2c28c45e2e..e85e841cf5 100644 --- a/pkg/workflow/compiler_safe_outputs_job.go +++ b/pkg/workflow/compiler_safe_outputs_job.go @@ -148,14 +148,15 @@ func (c *Compiler) buildConsolidatedSafeOutputsJob(data *WorkflowData, mainJobNa // Check if any project-handler-manager-supported types are enabled // These types require GH_AW_PROJECT_GITHUB_TOKEN and are processed separately + // Note: update-project and create-project-status-update are handled by the unified handler, + // not the project handler manager, so they are excluded from this check hasProjectHandlerManagerTypes := data.SafeOutputs.CreateProjects != nil || - data.SafeOutputs.CreateProjectStatusUpdates != nil || - data.SafeOutputs.UpdateProjects != nil || data.SafeOutputs.CopyProjects != nil - // 1. Project Handler Manager step (processes create_project, update_project, copy_project, etc.) + // 1. Project Handler Manager step (processes create_project, copy_project) // These types require GH_AW_PROJECT_GITHUB_TOKEN and must be processed separately from the main handler manager // This runs FIRST to ensure projects exist before issues/PRs are created and potentially added to them + // Note: update-project and create-project-status-update are handled by the unified handler if hasProjectHandlerManagerTypes { consolidatedSafeOutputsJobLog.Print("Using project handler manager for project-related safe outputs") projectHandlerManagerSteps := c.buildProjectHandlerManagerStep(data) @@ -169,15 +170,10 @@ func (c *Compiler) buildConsolidatedSafeOutputsJob(data *WorkflowData, mainJobNa // Add permissions for project-related types // Note: Projects v2 cannot use GITHUB_TOKEN; it requires a PAT or GitHub App token // The permissions here are for workflow-level permissions, actual API calls use GH_AW_PROJECT_GITHUB_TOKEN + // Only create_project and copy_project are handled by the project handler manager if data.SafeOutputs.CreateProjects != nil { permissions.Merge(NewPermissionsContentsReadProjectsWrite()) } - if data.SafeOutputs.CreateProjectStatusUpdates != nil { - permissions.Merge(NewPermissionsContentsReadProjectsWrite()) - } - if data.SafeOutputs.UpdateProjects != nil { - permissions.Merge(NewPermissionsContentsReadProjectsWrite()) - } if data.SafeOutputs.CopyProjects != nil { permissions.Merge(NewPermissionsContentsReadProjectsWrite()) } @@ -254,6 +250,14 @@ func (c *Compiler) buildConsolidatedSafeOutputsJob(data *WorkflowData, mainJobNa if data.SafeOutputs.DispatchWorkflow != nil { permissions.Merge(NewPermissionsActionsWrite()) } + // Project-related types now handled by the unified handler + // (not the separate project handler manager step) + if data.SafeOutputs.UpdateProjects != nil { + permissions.Merge(NewPermissionsContentsReadProjectsWrite()) + } + if data.SafeOutputs.CreateProjectStatusUpdates != nil { + permissions.Merge(NewPermissionsContentsReadProjectsWrite()) + } // If create-issue is configured with assignees: copilot, run a follow-up step to // assign the Copilot coding agent. The handler manager exports the list via diff --git a/pkg/workflow/compiler_safe_outputs_steps_test.go b/pkg/workflow/compiler_safe_outputs_steps_test.go index 38495bad45..a471f7d23e 100644 --- a/pkg/workflow/compiler_safe_outputs_steps_test.go +++ b/pkg/workflow/compiler_safe_outputs_steps_test.go @@ -392,21 +392,6 @@ func TestBuildProjectHandlerManagerStep(t *testing.T) { "safe_output_project_handler_manager.cjs", }, }, - { - name: "project handler manager with create_project_status_update", - safeOutputs: &SafeOutputsConfig{ - CreateProjectStatusUpdates: &CreateProjectStatusUpdateConfig{ - GitHubToken: "${{ secrets.PROJECTS_PAT }}", - }, - }, - checkContains: []string{ - "name: Process Project-Related Safe Outputs", - "id: process_project_safe_outputs", - "GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG", - "GH_AW_PROJECT_GITHUB_TOKEN: ${{ secrets.PROJECTS_PAT }}", - "github-token: ${{ secrets.PROJECTS_PAT }}", - }, - }, { name: "project handler manager without custom token uses default", safeOutputs: &SafeOutputsConfig{ @@ -420,25 +405,6 @@ func TestBuildProjectHandlerManagerStep(t *testing.T) { "github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}", }, }, - { - name: "project handler manager with project URL from frontmatter", - safeOutputs: &SafeOutputsConfig{ - UpdateProjects: &UpdateProjectConfig{ - BaseSafeOutputConfig: BaseSafeOutputConfig{ - Max: 10, - }, - }, - }, - parsedFrontmatter: &FrontmatterConfig{ - Project: &ProjectConfig{ - URL: "https://github.com/orgs/test-org/projects/123", - }, - }, - checkContains: []string{ - "name: Process Project-Related Safe Outputs", - "GH_AW_PROJECT_URL: \"https://github.com/orgs/test-org/projects/123\"", - }, - }, } for _, tt := range tests { diff --git a/pkg/workflow/create_project_status_update_handler_config_test.go b/pkg/workflow/create_project_status_update_handler_config_test.go index e12efb5808..163105f2a8 100644 --- a/pkg/workflow/create_project_status_update_handler_config_test.go +++ b/pkg/workflow/create_project_status_update_handler_config_test.go @@ -125,8 +125,9 @@ Test workflow // TestCreateProjectStatusUpdateHandlerConfigLoadedByManager verifies that when // create-project-status-update is configured alongside other handlers like create-issue or add-comment, -// the project handler manager is properly configured to load the create_project_status_update handler -// (separately from the main handler manager which handles create-issue) +// it is properly included in the main handler manager config (not the project handler manager). +// Note: As of recent changes, create-project-status-update is handled by the unified handler, +// not the separate project handler manager step. func TestCreateProjectStatusUpdateHandlerConfigLoadedByManager(t *testing.T) { tmpDir := testutil.TempDir(t, "handler-config-test") @@ -164,7 +165,6 @@ Test workflow // Extract main handler config JSON lines := strings.Split(compiledStr, "\n") var mainConfigJSON string - var projectConfigJSON string for _, line := range lines { if strings.Contains(line, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG:") { parts := strings.SplitN(line, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG:", 2) @@ -174,36 +174,28 @@ Test workflow mainConfigJSON = strings.ReplaceAll(mainConfigJSON, "\\\"", "\"") } } - if strings.Contains(line, "GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG:") { - parts := strings.SplitN(line, "GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG:", 2) - if len(parts) == 2 { - projectConfigJSON = strings.TrimSpace(parts[1]) - projectConfigJSON = strings.Trim(projectConfigJSON, "\"") - projectConfigJSON = strings.ReplaceAll(projectConfigJSON, "\\\"", "\"") - } - } } require.NotEmpty(t, mainConfigJSON, "Failed to extract GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG JSON") - require.NotEmpty(t, projectConfigJSON, "Failed to extract GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG JSON") // Verify create_issue is in the main handler config assert.Contains(t, mainConfigJSON, "create_issue", "Expected create_issue in main handler config") - // Verify create_project_status_update is in the project handler config (NOT in main config) - assert.NotContains(t, mainConfigJSON, "create_project_status_update", - "create_project_status_update should not be in main handler config") - assert.Contains(t, projectConfigJSON, "create_project_status_update", - "Expected create_project_status_update in project handler config") + // Verify create_project_status_update is also in the main handler config + // (as of recent changes, it's handled by the unified handler, not a separate project handler step) + assert.Contains(t, mainConfigJSON, "create_project_status_update", + "Expected create_project_status_update in main handler config") - // Verify max values are correct - assert.Contains(t, projectConfigJSON, `"create_project_status_update":{"max":2}`, - "Expected create_project_status_update with max:2 in project handler config") + // Verify max value is correct + assert.Contains(t, mainConfigJSON, `"max":2`, + "Expected max:2 in create_project_status_update handler config") } // TestCreateProjectStatusUpdateWithProjectURLConfig verifies that the project URL configuration -// is properly set as an environment variable when configured in safe-outputs +// is properly set in the handler config when configured in safe-outputs. +// Note: Since create-project-status-update is now handled by the unified handler (not the project handler manager), +// the project URL is passed as part of the handler config, not as a separate GH_AW_PROJECT_URL environment variable. func TestCreateProjectStatusUpdateWithProjectURLConfig(t *testing.T) { tmpDir := testutil.TempDir(t, "handler-config-test") @@ -234,7 +226,7 @@ Test workflow compiledStr := string(compiledContent) - // Verify GH_AW_PROJECT_URL environment variable is set - require.Contains(t, compiledStr, "GH_AW_PROJECT_URL:", "Expected GH_AW_PROJECT_URL environment variable") - require.Contains(t, compiledStr, "https://github.com/orgs/nonexistent-test-org-67890/projects/88888", "Expected project URL in environment variable") + // Verify project URL is in the handler config + require.Contains(t, compiledStr, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG", "Expected main handler config") + require.Contains(t, compiledStr, "https://github.com/orgs/nonexistent-test-org-67890/projects/88888", "Expected project URL in handler config") } diff --git a/pkg/workflow/update_project_handler_config_test.go b/pkg/workflow/update_project_handler_config_test.go index d7b35f7c9c..4631781847 100644 --- a/pkg/workflow/update_project_handler_config_test.go +++ b/pkg/workflow/update_project_handler_config_test.go @@ -43,8 +43,9 @@ Test workflow require.NoError(t, err, "Failed to read compiled output") compiledStr := string(compiledContent) - require.Contains(t, compiledStr, "GH_AW_SAFE_OUTPUTS_PROJECT_HANDLER_CONFIG", "Expected project handler config env var") - require.Contains(t, compiledStr, "update_project", "Expected update_project in project handler config") + // Note: update-project is now in the main handler config, not the project handler config + require.Contains(t, compiledStr, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG", "Expected main handler config env var") + require.Contains(t, compiledStr, "update_project", "Expected update_project in handler config") // field_definitions uses underscore naming in the JSON config passed to JS require.True( @@ -84,7 +85,10 @@ Test workflow compiledStr := string(compiledContent) - // Verify GH_AW_PROJECT_URL environment variable is set - require.Contains(t, compiledStr, "GH_AW_PROJECT_URL:", "Expected GH_AW_PROJECT_URL environment variable") - require.Contains(t, compiledStr, "https://github.com/orgs/nonexistent-test-org-12345/projects/99999", "Expected project URL in environment variable") + // Note: Since update-project is no longer in the project handler manager, + // GH_AW_PROJECT_URL is not set when only update-project is configured. + // update-project is now handled by the unified handler, which doesn't set GH_AW_PROJECT_URL. + // The project URL is passed as part of the handler config instead. + require.Contains(t, compiledStr, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG", "Expected main handler config") + require.Contains(t, compiledStr, "https://github.com/orgs/nonexistent-test-org-12345/projects/99999", "Expected project URL in handler config") }