Skip to content

chore: merge dev into main#1493

Merged
zbigniewsobiecki merged 12 commits into
mainfrom
dev
Jul 13, 2026
Merged

chore: merge dev into main#1493
zbigniewsobiecki merged 12 commits into
mainfrom
dev

Conversation

@zbigniewsobiecki

Copy link
Copy Markdown
Member

Summary

Promotion of the JIRA scoped API token feature set (MNG-1734 and sub-stories):

  • feat(jira): add shared resolveJiraApiBaseUrl host resolver with per-baseUrl cloudId cache (MNG-1737)
  • feat(jira): thread authType through worker and CLI credential scopes (MNG-1741)
  • refactor(jira): export JiraAuthType from config-schema as single source of truth
  • feat(jira): route dashboard webhook management + label seeding through effective host (MNG-1740)
  • fix(router): route JIRA ack/PM comments through effective host for scoped tokens (MNG-1739)
  • feat(jira): route API client through effective host for scoped tokens (MNG-1738)
  • feat(jira): thread authType through discovery + verification endpoints (MNG-1743)
  • feat(jira-wizard): add API-token-with-scopes auth-type selector (MNG-1744)
  • docs(jira): document scoped API token support (MNG-1745)
  • fix(config): thread JIRA authType through configMapper + self-correcting review-policy file

🤖 Generated with Claude Code

https://claude.ai/code/session_011ZaMpedeE8PXsix84cWsq1

Cascade Bot and others added 12 commits July 10, 2026 15:40
…ing review-policy file

Address review feedback on PR #1483:

- Thread the optional JIRA `authType` through the runtime DB-load path
  (`configMapper` `JiraIntegrationConfig`, `ProjectConfigRaw['jira']`, and
  `buildJiraConfig`). `buildJiraConfig` hand-picks fields, so `authType` was
  dropped before `jiraConfigSchema` re-parses and `ProjectConfig.jira.authType`
  always loaded back as `undefined`. Add mapper-level regression tests.
- Reword `JiraCredentials.authType` JSDoc so it no longer overstates behavior:
  the field is reserved on the credentials shape but no call site populates it yet.
- Write the review-event-policy file UNCONDITIONALLY with the run's resolved
  policy (both `all` and `comment-only`) so it self-corrects instead of relying
  on `/tmp` never being reused. CLI env > file > default precedence unchanged.
  Add tests asserting the write; mock only `writeFileSync` to avoid real disk I/O.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
…ce of truth

Eliminates the duplicated 'basic' | 'scoped' literal union that lived
independently in JiraConfig, JiraCredentials, and jiraConfigSchema.
Adding a third auth mode now requires one edit in config-schema.ts only.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Claude-Session: https://claude.ai/code/session_011ZaMpedeE8PXsix84cWsq1
…1484)

* feat(jira): thread authType through worker and CLI credential scopes

Carry the JIRA authType ('basic' | 'scoped') into the in-worker and CLI
credential scopes so agent runs and friction reports route JIRA REST calls
through the correct host.

- secretBuilder injects CASCADE_JIRA_AUTH_TYPE (= jiraConfig.authType ?? 'basic')
  alongside CASCADE_JIRA_BASE_URL.
- cli/base wrapWithCredentialScopes threads CASCADE_JIRA_AUTH_TYPE into
  withJiraCredentials; synthesizeProjectFromEnv sets jira.authType from it.
- JiraIntegration.withCredentials reads getJiraConfig(project)?.authType and
  passes it into withJiraCredentials.
- reportFriction env-synthesized JIRA config includes authType.
- New shared normalizeJiraAuthType() validates the raw env var back into the
  'basic' | 'scoped' domain, defaulting to 'basic' for absent/unknown values.

Refs: https://linear.app/issue/MNG-1741

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* test(cli): make review-event-policy sidecar test hermetic against policy file

resolveEventPolicyFromEnv() falls back to reading REVIEW_EVENT_POLICY_FILE
(a hardcoded global /tmp path) when CASCADE_REVIEW_EVENT_POLICY is absent or
invalid. The sibling suite create-pr-review.test.ts writes that file, and
unit-core runs test files in parallel forks (isolate: false), so a leftover
policy file could leak 'comment-only' into this suite's env-absent / invalid
cases and fail them (surfaced when both files land in the same `--changed`
subset). Remove the file in the policy suite's beforeEach/afterEach so it is
hermetic and never leaks the file to sibling suites.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

---------

Co-authored-by: Cascade Bot <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
Replaces the two hand-written `'basic' | 'scoped'` unions in
configMapper.ts (the `JiraIntegrationConfig` interface and the
`mapProjectRow` return type) with the shared `JiraAuthType` from
config-schema.ts. Adding a third auth mode is now genuinely one edit
— the `z.enum(...)` — instead of leaving these two annotations
silently narrower than the schema. No cycle risk: config-schema.ts
only imports zod.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
…h the effective host (MNG-1740) (#1487)

* feat(jira): route dashboard webhook management + label seeding through the effective host (MNG-1740)

* fix(jira): make router-level webhook dedup list best-effort

The dashboard "Create Webhook" flow lists existing JIRA webhooks at the
router level (maybeCreateJiraWebhook) before jiraCreateWebhook runs. That
list was not best-effort, so a scoped token lacking webhook scopes — which
returns 401 on GET /rest/api/3/webhook (MNG-1735) — threw a generic
"Failed to list JIRA webhooks: 401" and masked jiraCreateWebhook's
actionable 401/403 scope / manual-registration message.

Wrap the router-level list in the same best-effort try/catch already used
inside jiraCreateWebhook so dedup is skipped on a denied list and the
create's actionable error surfaces in the wizard. Adds a regression test
asserting the FORBIDDEN scope message reaches the caller (and the POST
create is actually attempted) when the dedup list is denied.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

---------

Co-authored-by: Cascade Bot <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
…shared-type

refactor(jira): export JiraAuthType from config-schema as single source of truth
const globexBaseUrl = 'https://globex.atlassian.net';
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
const url = String(input);
const cloudId = url.startsWith(globexBaseUrl) ? 'cloud-globex' : 'cloud-acme';
@zbigniewsobiecki zbigniewsobiecki merged commit 0bc6d18 into main Jul 13, 2026
14 of 15 checks passed
@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.81443% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/api/routers/webhooks/jira.ts 89.47% 6 Missing ⚠️
src/jira/client.ts 88.37% 5 Missing ⚠️
src/backends/secretOrchestrator.ts 66.66% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants