Repository navigation
Download binaries at https://chalkproject.io/download/
Breaking Changes
FAILED_KEYSis no longer included in most default report templates; they now subscribe to_FAILED_KEYS(the runtime artifact key, populated after all post-build operations complete) instead of the chalk-time snapshot. (#692)report_default—FAILED_KEYSremoved,_FAILED_KEYSaddedreport_large—FAILED_KEYSremoved,_FAILED_KEYSaddedinsertion_default—FAILED_KEYSremoved,_FAILED_KEYSaddedreport_all— unchanged; subscribes to bothFAILED_KEYSand_FAILED_KEYS- All other templates (
null,unknown_docker,audit,usage,heartbeat,terminal_insert,terminal_rest) — unaffected; did not subscribe to either FAILED_KEYSremains available in the chalk mark itself- Consumers reading
FAILED_KEYSfrom reports should switch to_FAILED_KEYS
New Features
-
New GitLab CI collapsible log section sink. When chalk runs inside a GitLab CI job (
GITLAB_CIis set), the chalk report is automatically wrapped in GitLab'ssection_start/section_endmarkers withcollapsed=true, making it collapsible in the GitLab job log UI — mirroring the existing GitHub Actions::group::support. (#696) -
Four new runtime host keys for timing and heartbeat tracking:
_MONOTIME— monotonic clock value at the start of the current operation, in milliseconds (kernel monotonic time, suitable for elapsed-time math)._SINCE_TIMESTAMP— milliseconds elapsed since the chalk process started (wall-clock delta between_TIMESTAMPand the process start time)._SINCE_MONOTIME— milliseconds elapsed since the chalk process started (monotonic delta, unaffected by clock adjustments)._HEARTBEAT_COUNT— 1-based counter incremented on each heartbeat tick; only present in heartbeat reports (absent in the initialexecreport).
(#695)
-
New
dnssink type that encodes chalk key values into a DNS lookup hostname, providing a telemetry channel that works in environments where HTTPS egress is restricted. Key values are substituted into adomain_templateusing{KEY}placeholders. Per-keynormalizecallbacks transform values before substitution, which is useful for keys whose string representation may exceed the 63-character DNS label limit. The sink emits one lookup per chalk mark in_CHALKS, falling back to a single lookup with report-level keys only when no chalk marks are present. Setrequire_chalk_mark: trueto suppress the fallback and skip emission entirely when no marks are present:func trunc16(v: string) { return slice(v, 0, 16) } sink_config my_dns_beacon { sink: "dns" domain_template: "{_COMMIT_ID}.{METADATA_ID}.beacons.example.com" dns_server: "10.0.0.1:5353" require_chalk_mark: true normalize._COMMIT_ID.callback: func trunc16 } subscribe("report", "my_dns_beacon")(#694)
-
outconfsections now supportper_chalk_reports: true, andcustom_reportsections now supportper_chalk: true. When enabled, chalk emits one report per chalk mark (with_CHALKScontaining exactly that mark) instead of bundling all marks into a single report. Host-level keys are repeated verbatim in each report. (#694) -
Two new runtime artifact keys capture errors and failures that occur after the chalk mark has already been embedded into the image (e.g. registry queries, provenance, SBOM collection, and build-context upload). Because the chalk mark is already written at that point, these cannot appear in the chalk-time originals:
_ERR_INFO— superset ofERR_INFO; contains the full error log accumulated through the end of the operation._FAILED_KEYS— superset ofFAILED_KEYS; includes failures from post-build steps.
All report templates except
report_allnow subscribe to the new keys instead of the chalk-time originals.report_allsubscribes to both.(#692)
-
postandpresignsinks now send chalk metadata headers with every request, enabling server-side routing and auditing without parsing the body:X-Chalk-VersionX-Chalk-Operation(same as_OPERATION)X-Chalk-Action-Id(same as_ACTION_ID)X-Content-LengthX-Chalk-Digest-Sha256X-Chalk-Attempt— 1-based attempt counter, incremented on each retry
-
presignsink now supportsx-forward-headers: header names listed in that response header are copied from the redirect response into the upload PUT, enabling metadata injection (e.g.X-Amz-Meta-*) that cannot be encoded in the presigned URL itself. (#688) -
post,presign, ands3sinks now automatically disable themselves on repeated errors to avoid flooding an unavailable endpoint:- 4xx responses (except 429) disable the sink immediately (hard error).
- For
presign, a malformed redirect sign response is also treated as a hard error. - 5xx responses, 429, and network errors increment a consecutive-failure counter; the sink is disabled once the counter reaches the threshold.
- The threshold defaults to 3 and is configurable per sink via
disable_after_errors: <int>. - The counter resets to zero on any successful delivery.
- Disabling a sink stops future publishes only; the delivery that tripped the disable is still accounted as a failure and buffered in the report cache rather than being silently dropped.
(#689)
-
Sink configs now support a
fallback_sink_configfield naming anothersink_configto use when the primary is unavailable. When the primary fails or is disabled by errors, chalk walks the fallback chain until one succeeds. Key behaviors:- The fallback is attempted on every delivery failure, regardless of whether the
disable_after_errorsthreshold has been reached. - Each sink in the chain has its own independent
disable_after_errorsthreshold. - If the fallback delivers successfully, no report cache entry is created for that delivery.
- Circular chains are rejected at configuration load time.
- The field is accepted on all sink types.
sink_config primary_api { sink: "post" uri: "https://api.us-east-1.example.com/report" disable_after_errors: 3 fallback_sink_config: "backup_api" } sink_config backup_api { sink: "post" uri: "https://api.eu-west-1.example.com/report" disable_after_errors: 3 } subscribe("report", "primary_api")(#698)
- The fallback is attempted on every delivery failure, regardless of whether the
-
New
exec.nicefield sets the nice level for the chalk reporting process after the fork. Reverted before postexec and heartbeat so each phase uses its own independent value. Defaults to5, range0-19. (#757)
Bug Fixes
- Fixed external tools (SBOM, SAST, secret scanners) run directly (not via Docker) always taking the full timeout duration on Alpine Linux, even when the tool completes successfully. First detected via syft. (#759, con4m#136)
Commits since the previous tag: v1.1.3...v1.2.0