test(stateful-templates): group email template journey + load group secrets (M5.5)
CLI journey: set a group secret, apply a group [[triggers.email]] template referencing it, create an app under the group → `pic triggers ls --app` shows a materialized email trigger; re-apply is a NoOp. Required loading a group's own set-secret names into CurrentState (was hardcoded empty) so the apply plan-time email-secret check resolves the ref against the GROUP store. Informational only — the secrets diff is never executed on apply (secrets are set out-of-band via `pic secret set`); the state token now folds in group secrets, matching apps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2593,7 +2593,8 @@ impl ApplyService {
|
||||
.list_for_app(app_id)
|
||||
.await
|
||||
.map_err(|e| ApplyError::Backend(e.to_string()))?,
|
||||
self.all_secret_names(app_id).await?,
|
||||
self.all_secret_names(crate::secrets_service::SecretOwner::App(app_id))
|
||||
.await?,
|
||||
VarOwner::App(app_id),
|
||||
),
|
||||
ApplyOwner::Group(group_id) => (
|
||||
@@ -2611,7 +2612,12 @@ impl ApplyService {
|
||||
.list_for_group(group_id)
|
||||
.await
|
||||
.map_err(|e| ApplyError::Backend(e.to_string()))?,
|
||||
Vec::new(),
|
||||
// §4.5 M5.5: a group's own set secrets — the plan check for an
|
||||
// email TEMPLATE resolves `inbound_secret_ref` against the
|
||||
// GROUP store, and the state token folds them in. Informational
|
||||
// in the secrets diff only (apply never writes secrets).
|
||||
self.all_secret_names(crate::secrets_service::SecretOwner::Group(group_id))
|
||||
.await?,
|
||||
VarOwner::Group(group_id),
|
||||
),
|
||||
};
|
||||
@@ -2658,17 +2664,16 @@ impl ApplyService {
|
||||
})
|
||||
}
|
||||
|
||||
async fn all_secret_names(&self, app_id: AppId) -> Result<Vec<String>, ApplyError> {
|
||||
async fn all_secret_names(
|
||||
&self,
|
||||
owner: crate::secrets_service::SecretOwner,
|
||||
) -> Result<Vec<String>, ApplyError> {
|
||||
let mut names = Vec::new();
|
||||
let mut cursor: Option<String> = None;
|
||||
loop {
|
||||
let page = self
|
||||
.secrets
|
||||
.list_names(
|
||||
crate::secrets_service::SecretOwner::App(app_id),
|
||||
cursor.as_deref(),
|
||||
200,
|
||||
)
|
||||
.list_names(owner, cursor.as_deref(), 200)
|
||||
.await
|
||||
.map_err(|e| ApplyError::Backend(e.to_string()))?;
|
||||
names.extend(page.names);
|
||||
|
||||
Reference in New Issue
Block a user