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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Shared contracts and runtime libraries for CommerceKit GitHub Actions. This public repository is a pnpm monorepo, not a GitHub Marketplace Action. There is no root `action.yml`.

The source manifests prepare `notification-contract@0.0.5` (unpublished candidate) and `ccv2-client@0.0.3` under the `preview` dist-tag. Source versions are not registry publication evidence. APIs remain pre-1.0; verify registry publication before installation. Placeholder reserved versions, if published later, are not supported dependencies.
The source manifests prepare `notification-contract@0.0.6` (unpublished candidate) and `ccv2-client@0.0.3` under the `preview` dist-tag. Source versions are not registry publication evidence. APIs remain pre-1.0; verify registry publication before installation. Placeholder reserved versions, if published later, are not supported dependencies.

| Package | Responsibility | Consumers |
| ------------------------------------------ | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
Expand Down Expand Up @@ -41,3 +41,8 @@ See [CONTRIBUTING](CONTRIBUTING.md) for individual commands, [compatibility poli
Package reservation, preview/stable publication and GitHub Releases are separate manually confirmed owner workflows. Publication never runs on push or PR. [RELEASING](RELEASING.md) describes two-phase recovery and coordinated stable gates. No package or Action is published by this implementation PR.

The manual publish workflow verifies the exact commit's CI/CodeQL results and publishes the tested tarball after an integrity check. A separate manual workflow verifies registry publication before creating a package-specific Git tag and GitHub Release. See [dispatch examples](RELEASING.md#dispatch-examples-after-merge-and-owner-approval). Tags do not trigger publication.

The [consistent Action reporting candidate](docs/action-reporting.md) adds shared
input snapshots, status styling, GitHub summary formatting and setup events.
Published 0.0.5 remains the registry baseline; candidate consumer readiness is
blocked until separately authorized 0.0.6 publication and normal repinning.
2 changes: 1 addition & 1 deletion compatibility/tests/release-safety.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
import { join } from 'node:path';
it('publication requires exact package/channel/confirmation and pre-1.0 version', () => {
for (const [name, version] of [
['notification-contract', '0.0.5'],
['notification-contract', '0.0.6'],
['ccv2-client', '0.0.3'],
])
expect(releasePlan(name, 'preview', 'PUBLISH-COMMERCEKIT-PREVIEW')).toMatchObject({
Expand Down
38 changes: 38 additions & 0 deletions compatibility/tests/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,41 @@ const invalidCleanupInputs: BuildCleanupInputSnapshot = {
void invalidCleanupInputs;
// @ts-expect-error cleanup warning support does not widen Deploy status
createDeploymentEvent({ status: 'warning', data: {} });

import {
createSetupEvent,
createActionInputContext,
captureActionInputs,
renderActionSummary,
getNotificationStyle,
type SetupEvent,
type NotificationInputContext,
type ActionInputDefinition,
type ActionSummaryOptions,
} from '../../packages/notification-contract/src/index.js';
const definitions: readonly ActionInputDefinition[] = [{ name: 'version' }];
const captured = captureActionInputs(
definitions,
() => 'latest',
() => {},
);
const inputContext: NotificationInputContext = createActionInputContext(definitions, captured, {
validated: true,
});
const setup: SetupEvent = createSetupEvent({
status: 'success',
data: { ...inputContext, version: '1.0.0' },
});
const summaryOptions: ActionSummaryOptions = {
title: 'Setup CommerceKit',
status: setup.status,
inputContext,
facts: [{ label: 'Version', value: '1.0.0' }],
};
const summary: string = renderActionSummary(summaryOptions);
void summary;
void getNotificationStyle('warning');
// @ts-expect-error setup cannot use a deployment handoff status
createSetupEvent({ status: 'action-required', data: {} });
// @ts-expect-error snapshots are display strings rather than raw objects
createActionInputContext(definitions, { version: {} }, { validated: false });
121 changes: 121 additions & 0 deletions docs/action-reporting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Consistent Action reporting candidate

The five release-candidate Actions are setup-commercekit, ccv2-build,
ccv2-deploy, ccv2-build-cleanup and notify. They share this reporting contract
through the existing notification-contract package. No new package, authentication
implementation, provider delivery, schedule or SAP operation is introduced.

## Visual contract

| Status | Icon | Meaning |
| --------------- | ---- | ----------------------------------------------------- |
| success | ✅ | The reported operation succeeded |
| failure | ❌ | The operation failed |
| warning | ⚠️ | The producer identified an issue that needs attention |
| action-required | ⚠️ | A deployment requires an explicit decision |
| internal-error | ❌ | The Action could not complete its operation |
| started | ℹ️ | The operation started |
| cancelled | ⏹️ | The operation was cancelled |

`getNotificationStyle` owns labels, icons, semantic tones and accent colors.
Cancellation remains neutral. A warning never changes a failed build/deployment
into success. Build and Deploy completed-status types remain unchanged.

Cards and summaries present the operation title/status, result facts, inputs,
issues and workflow reference in that order. Provider layouts retain native
Slack blocks and Teams containers/fact sets. GitHub summaries use escaped
Markdown headings and tables. Consumers provide meaningful human labels rather
than dumping raw objects or internal property names.

`renderActionSummary` is pure. The caller writes its result through the existing
GitHub Actions summary API on handled success, failure and warning. Summary or
notification generation failure must not replace the underlying operation result.
A delivery Action reports its own delivery outcome separately from the source
event severity: successful delivery of a failed build is successful delivery.

## Safe input context

`captureActionInputs` reads configured confidential fields first and registers
each value before reading public settings. `createActionInputContext` includes
every declared input name, effective values after validation, and safely captured
supplied values when validation failed. Exact input coverage is checked against
each Action's metadata by consumer tests.

- Authentication fields, webhook URLs, credentials and secret-bearing input
names always display `[REDACTED]`, including missing or invalid values.
- Known secrets and their encoded forms, Bearer/PAT/JWT-like values and
credential-bearing/query URLs are redacted before bounding display values.
- Event JSON, event-file paths, traffic JSON and free-form decision/cancellation
reasons show presence only. Arbitrary payloads are never copied into cards.
- Public API origins may be shown after strict origin validation. Authentication
token endpoints remain fully redacted.
- Display values are bounded to 256 Unicode code points. Truncation is explicit;
`inputsValidated` and `inputsTruncated` distinguish safe previews from execution
configuration. Provider previews may be shorter with a visible note.
- Common snapshots permit at most 50 kebab-case names and enforce confidential
placeholders in the schema. Cleanup's existing exact 14-name schema is retained.

The common summary renderer escapes HTML, Markdown, table separators, mentions
and newlines. It masks confidential names defensively even for a forged snapshot,
filters private links and preserves safe enterprise workflow URLs. Result tables
and decision tables are bounded to 50 rows, sections to eight, columns to eight,
links to three and the complete UTF-8 summary to 64 KiB, with an omission notice.

## Additive event support

Check, Build and Deploy data gain optional input-context and safe issue fields;
old payloads remain valid. Setup gains `commercekit.setup.completed`, public
`SetupEvent`/`SetupEventData` types and `createSetupEvent`. It records requested and
resolved version, target, build ID, cache result, duration and safe failure detail.
It does not expose executable paths or invent warnings for a cache hit.

The package contains no CLI execution, Action I/O or provider renderer. Factories
project known event fields and validate; callers retain endpoint-specific result
projection and register tokens with their existing masker.

## Provenance and rollout gate

Source prepares **0.0.6**, an unpublished candidate. Registry-backed baseline
0.0.5 is published; it lacks these shared helpers and the setup event. Existing
source baselines inspected for this change:

| Repository | Main inspected |
| ------------------------ | ------------------------------------------ |
| action-kit | `7cc2e8e6af46e7438064cc6205b22f4f7154eb94` |
| notify | `6331ff4a60956a3a2b546e84d737c9338ca46bda` |
| setup-commercekit | `7f650f3162ab027bfd784cf879832f44d3248584` |
| ccv2-build | `923535d589bd8cebece4f3cbf479608f9535c4c3` |
| ccv2-deploy | `bb6d1d6a2ac43a5b6e5b6831c78c5cf28bdb95ca` |
| ccv2-build-cleanup | `9b7ab34515a2fb8ed643f786f754e44e485868d2` |
| action-integration-tests | `e6cefd75d5a926ca2232ac06f332e5b4394a09b5` |

Candidate consumers must use the exact-source packed tarball only in isolated
private integration workspaces, recording source commits, tarball integrity and
bundle hashes. Normal registry dependencies/lockfiles must never pretend that
0.0.6 is published or contain developer-local links. Consumer readiness remains
**BLOCKED** until a separately authorized publication, exact registry repinning,
normal bundle regeneration and green validation. Publication and source merge
do not authorize release tags, deployment, provider sends or real SAP deletion.

## Validation

The additive contract suite passes **394 tests in 12 files** on Node 24.21.0
and pnpm 12.6.0. Notification-contract coverage is **100% statements, 99.64%
branches, 100% functions and 100% lines**. All existing 95% thresholds remain
unchanged, including the untouched CCv2 client package. Focused tests cover every
new status, confidential-first capture, all-input previews, forged snapshots,
malformed Unicode secrets, schema/type compatibility, private links, Markdown/
HTML escaping, explicit truncation and the UTF-8 summary cap.

Packed ESM, JSON schema, declarations and public export boundaries are exercised
with installed temporary consumers. Full quality, public scanning and audit must
pass before the exact-source tarball is retained for final consumer replay.
Candidate consumer totals and exact artifact/source/bundle fingerprints are
recorded separately; WIP artifact success is not final registry readiness.

Independent privacy review found and reproduced two gaps before publication:
known secrets encoded with lowercase/mixed-case percent hex, and Slack webhook
hosts using a trailing DNS dot. Regression tests now cover raw/URL/form encodings
with literal case preserved, forged cross-field snapshots, and case/encoded-host/
trailing-dot webhook variants in values and links. The existing shared redactor
and display policy were corrected without changing OAuth or transport.
22 changes: 17 additions & 5 deletions packages/notification-contract/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# notification-contract changelog

## 0.0.5 — unpublished candidate
## 0.0.6 — unpublished candidate

- Add shared bounded input snapshots, confidential-first capture, safe text
display, status styles and pure GitHub summary formatting.
- Add setup-completed events and optional input/issue context to existing Check,
Build and Deploy events, preserving their outcome semantics.
- Preserve the cleanup schema and provider/OAuth boundaries; handle malformed
Unicode secrets safely in encoded redaction forms.
- Redact mixed-case percent-encoded secret forms and canonical webhook hostname
variants in inputs, summaries and links.
- Registry readiness remains blocked until separately authorized publication.

## 0.0.5

Allow the existing `warning` status specifically for build cleanup through new
public `BuildCleanupStatus`, preserving Build/Deploy `CompletedStatus` semantics.
Expand All @@ -11,10 +23,10 @@ be literal `[REDACTED]`, public values are at most 256 characters, and at most t
safe issues are accepted. Issue factories project only safe code/message fields.
Old cleanup events remain valid and existing event meanings are unchanged.

Registry checks found published 0.0.4 and no 0.0.5. This source version is not a
published registry dependency. Consumers require coordinated source/tarball tests
and separately authorized publication before normal exact-version adoption.
No OAuth/transport, provider delivery, package publication or release change.
Published from `7cc2e8e6af46e7438064cc6205b22f4f7154eb94` by the owner-authorized
package-only workflow run 43667757934. Registry integrity matched the previously
tested source artifact. No Git tag, Action release, OAuth/transport change or
provider delivery implementation was introduced.

## 0.0.4

Expand Down
31 changes: 27 additions & 4 deletions packages/notification-contract/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @commercekit-tools/notification-contract

Provider-neutral NotificationEvent v1 types, schema and validation for Notify, Build, Deploy, future Check and reusable workflows. No CCv2 calls, CLI diagnostics, Action I/O, polling, provider rendering or webhook delivery.
Provider-neutral NotificationEvent v1 types, schema and validation for Notify, Build, Deploy, future Check and reusable workflows. It also provides pure status/summary formatting and bounded input display context. No CCv2 calls, CLI diagnostics, Action I/O, polling, provider rendering or webhook delivery.

Public exports: `NotificationEvent`, `NotificationStatus`, `NotificationEventType`, `NotificationSource`, `NotificationContext`, `NotificationLink`, `SafeNotificationError`, `CheckEventData`, `BuildEventData`, `DeploymentEventData`, `BuildCleanupEvent`, `BuildCleanupEventData`, `BuildCleanupStatus`, `BuildCleanupInputSnapshot`; `validateNotificationEvent`, `parseNotificationEventJson`, `validateNotificationLink`, `validateGitHubRunUrl`, `extractSafeGitHubContext`, `mergeProducerContext`, `mergeNotifierContext`, `createCheckEvent`, `createBuildEvent`, `createDeploymentEvent`, `createBuildCleanupEvent`, `redactKnownSecrets`, `sanitizeBoundedText`, `sanitizeLabel`, `sanitizeErrorMessage`.

Expand All @@ -22,7 +22,12 @@ Extraction reads only approved runner fields, never event payloads. Explicit pro

Install from GitHub Packages after a supported version is published. Configure `@commercekit-tools:registry=https://npm.pkg.github.com`; local users need a classic PAT with `read:packages` in user-level configuration. Consumer Actions need package Actions read access and `GITHUB_TOKEN` with `packages: read`. See the repository authentication guide. Pin exact versions, never ranges.

Source version: `0.0.5`, an **unpublished candidate**. Registry inspection verified published versions through `0.0.4`; `0.0.5` was absent. Do not pin `0.0.5` as a registry dependency until separately authorized publication is verified. The currently published `0.0.4` package lacks the additions below. Exact-source packed-tarball tests may validate candidate consumers in isolation; no machine-local link belongs in a normal lockfile. Stable API and coordinated consumer/Sandbox validation remain future gates. Reservation versions are unsupported.
Source version: `0.0.6`, an **unpublished candidate** for consistent ecosystem
reporting. Exact registry checks verified publication through `0.0.5`; that
version lacks the new helpers and setup event. Do not pin `0.0.6` as a registry
dependency until separately authorized publication is verified. Candidate tests
use exact-source packed tarballs in isolated private consumers with integrity
records; normal lockfiles must not contain machine-local links.

Independent package SemVer applies; stable breaking changes require a major increment. NotificationEvent schema version is separate from package version. Preserve current consumer contracts during migration. No telemetry or logging is performed. Use synthetic tests and register exact runtime secrets; pattern redaction cannot identify all secrets.

Expand All @@ -46,13 +51,14 @@ published 0.0.3 or older reject it. Verify 0.0.4 registry availability and the
matching Notify revision before enabling this integration; a source manifest
is not publication evidence.

## Cleanup warning and input context — 0.0.5 candidate
## Cleanup warning and input context — 0.0.5

This additive cleanup-only extension accepts the existing global `warning` status
through public `BuildCleanupStatus`; Build and Deploy continue using unchanged
`CompletedStatus`. Old cleanup events remain valid. A published 0.0.4 validator
rejects cleanup warnings, so producer and Notify revisions must be coordinated.
No publication, tag, release or consumer migration is performed by these changes.
The 0.0.5 package was subsequently published through authorized package-only
workflow run 43667757934. That publication created no Git tag or Action release.

`BuildCleanupEventData` adds optional `inputs`, `inputsValidated`,
`inputsTruncated`, `protectedCount`, `blockedCount` and `issues` fields. If an
Expand All @@ -78,3 +84,20 @@ The factory retains only code/message for each issue, dropping raw nested fields
then validates the event. Outcome/severity interpretation belongs to the producer:
a warning must not hide a deletion failure or unknown mutation result. Accepted
deletion counts still describe initiation rather than physical removal.

## Consistent Action reporting — 0.0.6 candidate

New public exports: `SetupEvent`, `SetupEventData`, `NotificationInputContext`,
`NotificationInputData`, `ActionInputDefinition`, `NotificationStyle`,
`ActionSummaryOptions`, `ActionSummarySection`, `createSetupEvent`,
`captureActionInputs`, `createActionInputContext`, `isConfidentialInputName`,
`sanitizeActionText`, `getNotificationStyle` and `renderActionSummary`.

Build, Deploy and Check data accept optional bounded input snapshots and issues.
Setup uses `commercekit.setup.completed`; completed Build/Deploy semantics are
unchanged. The shared renderer creates a bounded escaped GitHub summary string;
callers perform Action I/O and preserve operation outcomes if reporting fails.

Read the [format, masking, compatibility and rollout contract](../../docs/action-reporting.md).
The package remains one of the existing two action-kit packages. No provider
payload/delivery or OAuth/transport behavior is added here.
2 changes: 1 addition & 1 deletion packages/notification-contract/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@commercekit-tools/notification-contract",
"version": "0.0.5",
"version": "0.0.6",
"description": "Provider-neutral NotificationEvent v1 contracts and factories.",
"license": "MIT",
"type": "module",
Expand Down
Loading
Loading