Skip to content

Support channels in the provisioner API#4757

Merged
midigofrank merged 5 commits into
mainfrom
4522-support-channels-in-provisioner
May 18, 2026
Merged

Support channels in the provisioner API#4757
midigofrank merged 5 commits into
mainfrom
4522-support-channels-in-provisioner

Conversation

@midigofrank
Copy link
Copy Markdown
Collaborator

@midigofrank midigofrank commented May 15, 2026

Description

GET /api/provision/:id and POST /api/provision now round-trip channels alongside workflows and collections. JSON exposes destination_credential_id; YAML uses a hyphenated email-credential-name key under destination_credential (matching how jobs reference credentials).

Channel deletion is rejected with an actionable error directing the user to the dashboard. channel_requests have a RESTRICT FK that needs draining first, and the dashboard handles that transactionally — the provisioner shouldn't.

Channel changes emit the same audits as Channels.create_channel/2 and update_channel/3 (created/updated plus auth_method_added/removed/changed for the destination credential).

The :channels has_many was moved above :project_credentials on Project so Ecto's reverse-declaration child-processing order inserts project_credentials before channel_auth_methods, letting the destination FK resolve when both are created in the same import.

Closes #4522

Validation steps

  1. Create channels
  2. Export your project in the settings page
  3. Your downloaded yaml will contain the channels
  4. You can also validate this using the cli, right now using Support channels in provisioner kit#1412

AI Usage

Please disclose whether you've used AI anywhere in this PR (it's cool, we just
want to know!):

  • I have used Claude Code
  • I have used another model
  • I have not used AI

You can read more details in our
Responsible AI Policy

Pre-submission checklist

  • I have performed an AI review of my code (we recommend using /review
    with Claude Code)
  • I have implemented and tested all related authorization policies.
    (e.g., :owner, :admin, :editor, :viewer)
  • I have updated the changelog.
  • I have ticked a box in "AI usage" in this PR

GET /api/provision/:id and POST /api/provision now round-trip channels
alongside workflows and collections. JSON exposes destination_credential_id;
YAML uses a hyphenated email-credential-name key under destination_credential
(matching how jobs reference credentials).

Channel deletion is rejected with an actionable error directing the user to
the dashboard. channel_requests have a RESTRICT FK that needs draining
first, and the dashboard handles that transactionally — the provisioner
shouldn't.

Channel changes emit the same audits as Channels.create_channel/2 and
update_channel/3 (created/updated plus auth_method_added/removed/changed
for the destination credential). The provisioner runs a per-channel Multi
with Multi.put(:channel, ...) so it reuses Audit.audit_auth_method_changes/3
unchanged.

The :channels has_many was moved above :project_credentials on Project so
Ecto's reverse-declaration child-processing order inserts project_credentials
before channel_auth_methods, letting the destination FK resolve when both
are created in the same import.
@github-project-automation github-project-automation Bot moved this to New Issues in Core May 15, 2026
…ials

Two follow-ups from the channels-in-provisioner review:

1. Cross-project credential validation. maybe_add_project_credentials/2 now
   runs inside parse_document/2 so by the time channels and jobs are cast,
   the changeset's :project_credentials assoc holds the authoritative set of
   PCs for this project. channel_changeset and job_changeset share a
   validate_project_credential_in_project/2 helper that rejects any
   project_credential_id outside that set. Mirrors the existing Job FK
   constraint message ("credential doesn't exist or isn't available in this
   project") and closes the gap for the channel destination credential.

2. Batched channel audits. Channels.Audit.audit_auth_method_changes/4 now
   takes the channel struct directly (no more :channel Multi-state lookup)
   and generates unique step keys via System.unique_integer/1, so it
   composes into a larger Multi any number of times. The provisioner folds
   every channel's audits into a single Multi and runs one transaction
   instead of one per channel. Channels.create_channel/2 keeps the
   deferred-id case working via Multi.merge; Channels.update_channel/3
   passes the channel directly.

Tests cover cross-project rejection for both channel destination
credentials and job credentials.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

❌ Patch coverage is 91.66667% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.04%. Comparing base (928c441) to head (7a933df).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/lightning/projects/provisioner.ex 89.74% 4 Missing ⚠️
lib/lightning/channels/audit.ex 84.61% 2 Missing ⚠️
lib/lightning/export_utils.ex 94.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4757      +/-   ##
==========================================
+ Coverage   90.02%   90.04%   +0.02%     
==========================================
  Files         448      448              
  Lines       22487    22557      +70     
==========================================
+ Hits        20243    20312      +69     
- Misses       2244     2245       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@midigofrank midigofrank marked this pull request as ready for review May 15, 2026 10:34
@midigofrank midigofrank requested a review from elias-ba May 15, 2026 10:34
@github-actions
Copy link
Copy Markdown

Security Review ✅

  • S0 (project scoping): New validate_project_credential_in_project/2 in lib/lightning/projects/provisioner.ex:537 rejects any project_credential_id not in this project's PC set (derived from loaded PCs plus user-owned additions via maybe_add_project_credentials); tests at test/lightning/projects/provisioner_test.exs:1459 and :1496 cover the channel and job cross-project rejection paths.
  • S1 (authorization): N/A, no new web-layer entrypoints — provisioner-internal validation refactor only.
  • S2 (audit trail): Same channel_created/updated and auth_method_added/removed/changed events are still emitted; Channels.Audit.audit_auth_method_changes/4 (lib/lightning/channels/audit.ex:35) now uses System.unique_integer/1 step keys so audits can be batched per channel in one Multi without key collisions.

Copy link
Copy Markdown
Contributor

@elias-ba elias-ba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice one dude 👏🏽

@midigofrank midigofrank merged commit fdee616 into main May 18, 2026
6 of 7 checks passed
@midigofrank midigofrank deleted the 4522-support-channels-in-provisioner branch May 18, 2026 13:47
@github-project-automation github-project-automation Bot moved this from New Issues to Done in Core May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Add channels to project.yaml

2 participants