Skip to content
Open
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
8 changes: 8 additions & 0 deletions config/300-crds/300-pipelinerun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2364,6 +2364,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -2744,6 +2746,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -3017,6 +3021,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -5463,6 +5469,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down
50 changes: 50 additions & 0 deletions config/300-crds/300-taskrun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -2152,6 +2154,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -3996,6 +4000,48 @@ spec:
type:
description: Type of condition.
type: string
notices:
description: Notices are structured messages emitted by controllers that do not affect the task's success/failure status.
type: array
items:
description: Notice represents a structured message emitted by a controller that does not affect the run's success/failure status.
type: object
required:
- level
- message
properties:
file:
description: |-
File is the source file path related to this notice.
Used by VCS integrations to create inline annotations.
Maximum length: 256 characters.
type: string
maxLength: 256
level:
description: |-
Level indicates the severity of the notice.
Valid values: "info", "warning".
type: string
enum:
- info
- warning
message:
description: |-
Message is the human-readable notice text.
Maximum length: 1024 characters.
type: string
maxLength: 1024
startLine:
description: |-
StartLine is the starting line number in the source file (1-based).
Pointer type so that absence (nil) is distinguishable from line 0.
type: integer
step:
description: |-
Step is the name of the step that emitted this notice.
Empty for controller-emitted notices.
type: string
x-kubernetes-list-type: atomic
observedGeneration:
description: |-
ObservedGeneration is the 'Generation' of the Service that
Expand Down Expand Up @@ -4033,6 +4079,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down Expand Up @@ -4298,6 +4346,8 @@ spec:
type: boolean
enableKubernetesSidecar:
type: boolean
enableNotices:
type: boolean
enableParamEnum:
type: boolean
enableProvenanceInStatus:
Expand Down
2 changes: 2 additions & 0 deletions config/config-feature-flags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ data:
# Setting this flag to "true" will enable the use of Artifacts in Steps
# This feature is in preview mode and not implemented yet. Please check #7693 for updates.
enable-artifacts: "false"
# Setting this flag to "true" will enable controller notices in TaskRun status.
enable-notices: "false"
# Setting this flag to "true" will enable the built-in param input validation via param enum.
enable-param-enum: "false"
# Setting this flag to "pipeline,pipelinerun,taskrun" will prevent users from creating
Expand Down
40 changes: 40 additions & 0 deletions docs/pipeline-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,44 @@ _Appears in:_
| `params` _[Params](#params)_ | Params is a list of parameters used to fan out the pipelineTask<br />Params takes only `Parameters` of type `"array"`<br />Each array element is supplied to the `PipelineTask` by substituting `params` of type `"string"` in the underlying `Task`.<br />The names of the `params` in the `Matrix` must match the names of the `params` in the underlying `Task` that they will be substituting. | | |


#### Notice



Notice represents a structured message emitted by a controller that does not affect the run's success/failure status.



_Appears in:_
- [TaskRunStatus](#taskrunstatus)
- [TaskRunStatusFields](#taskrunstatusfields)

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `level` _[NoticeLevel](#noticelevel)_ | Level indicates the severity of the notice.<br />Valid values: "info", "warning". | | Enum: [info warning] <br /> |
| `message` _string_ | Message is the human-readable notice text.<br />Maximum length: 1024 characters. | | MaxLength: 1024 <br /> |
| `step` _string_ | Step is the name of the step that emitted this notice.<br />Empty for controller-emitted notices. | | Optional: \{\} <br /> |
| `file` _string_ | File is the source file path related to this notice.<br />Used by VCS integrations to create inline annotations.<br />Maximum length: 256 characters. | | MaxLength: 256 <br />Optional: \{\} <br /> |
| `startLine` _integer_ | StartLine is the starting line number in the source file (1-based).<br />Pointer type so that absence (nil) is distinguishable from line 0. | | Optional: \{\} <br /> |


#### NoticeLevel

_Underlying type:_ _string_

NoticeLevel indicates the severity of a notice.



_Appears in:_
- [Notice](#notice)

| Field | Description |
| --- | --- |
| `info` | NoticeLevelInfo represents an informational message, no action needed.<br /> |
| `warning` | NoticeLevelWarning represents something to address, but not blocking.<br /> |


#### OnErrorType

_Underlying type:_ _string_
Expand Down Expand Up @@ -1578,6 +1616,7 @@ _Appears in:_
| `retriesStatus` _[RetriesStatus](#retriesstatus)_ | RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures.<br />All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. | | Schemaless: \{\} <br />Optional: \{\} <br /> |
| `results` _[TaskRunResult](#taskrunresult) array_ | Results are the list of results written out by the task's containers | | Optional: \{\} <br /> |
| `artifacts` _[Artifacts](#artifacts)_ | Artifacts are the list of artifacts written out by the task's containers | | Optional: \{\} <br /> |
| `notices` _[Notice](#notice) array_ | Notices are structured messages emitted by controllers that do not affect the task's success/failure status. | | Optional: \{\} <br /> |
| `sidecars` _[SidecarState](#sidecarstate) array_ | The list has one entry per sidecar in the manifest. Each entry is<br />represents the imageid of the corresponding sidecar. | | |
| `taskSpec` _[TaskSpec](#taskspec)_ | TaskSpec contains the Spec from the dereferenced Task definition used to instantiate this TaskRun. | | |
| `provenance` _[Provenance](#provenance)_ | Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.). | | Optional: \{\} <br /> |
Expand Down Expand Up @@ -1606,6 +1645,7 @@ _Appears in:_
| `retriesStatus` _[RetriesStatus](#retriesstatus)_ | RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures.<br />All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. | | Schemaless: \{\} <br />Optional: \{\} <br /> |
| `results` _[TaskRunResult](#taskrunresult) array_ | Results are the list of results written out by the task's containers | | Optional: \{\} <br /> |
| `artifacts` _[Artifacts](#artifacts)_ | Artifacts are the list of artifacts written out by the task's containers | | Optional: \{\} <br /> |
| `notices` _[Notice](#notice) array_ | Notices are structured messages emitted by controllers that do not affect the task's success/failure status. | | Optional: \{\} <br /> |
| `sidecars` _[SidecarState](#sidecarstate) array_ | The list has one entry per sidecar in the manifest. Each entry is<br />represents the imageid of the corresponding sidecar. | | |
| `taskSpec` _[TaskSpec](#taskspec)_ | TaskSpec contains the Spec from the dereferenced Task definition used to instantiate this TaskRun. | | |
| `provenance` _[Provenance](#provenance)_ | Provenance contains some key authenticated metadata about how a software artifact was built (what sources, what inputs/outputs, etc.). | | Optional: \{\} <br /> |
Expand Down
13 changes: 13 additions & 0 deletions pkg/apis/config/feature_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ const (
EnableCELInWhenExpression = "enable-cel-in-whenexpression"
// EnableArtifacts is the flag to enable the use of Artifacts in Steps
EnableArtifacts = "enable-artifacts"
// EnableNotices is the flag to enable controller notices in TaskRun status
EnableNotices = "enable-notices"
// EnableParamEnum is the flag to enabled enum in params
EnableParamEnum = "enable-param-enum"
// EnableConciseResolverSyntax is the flag to enable concise resolver syntax
Expand Down Expand Up @@ -172,6 +174,13 @@ var (
Enabled: DefaultAlphaFeatureEnabled,
}

// DefaultEnableNotices is the default PerFeatureFlag value for EnableNotices
DefaultEnableNotices = PerFeatureFlag{
Name: EnableNotices,
Stability: AlphaAPIFields,
Enabled: DefaultAlphaFeatureEnabled,
}

// DefaultEnableParamEnum is the default PerFeatureFlag value for EnableParamEnum
DefaultEnableParamEnum = PerFeatureFlag{
Name: EnableParamEnum,
Expand Down Expand Up @@ -230,6 +239,7 @@ type FeatureFlags struct {
EnableStepActions bool `json:"enableStepActions,omitempty"`
EnableParamEnum bool `json:"enableParamEnum,omitempty"`
EnableArtifacts bool `json:"enableArtifacts,omitempty"`
EnableNotices bool `json:"enableNotices,omitempty"`
DisableInlineSpec string `json:"disableInlineSpec,omitempty"`
EnableConciseResolverSyntax bool `json:"enableConciseResolverSyntax,omitempty"`
EnableKubernetesSidecar bool `json:"enableKubernetesSidecar,omitempty"`
Expand Down Expand Up @@ -335,6 +345,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) {
if err := setPerFeatureFlag(EnableArtifacts, DefaultEnableArtifacts, &tc.EnableArtifacts); err != nil {
return nil, err
}
if err := setPerFeatureFlag(EnableNotices, DefaultEnableNotices, &tc.EnableNotices); err != nil {
return nil, err
}

if err := setFeatureInlineSpec(cfgMap, DisableInlineSpec, DefaultDisableInlineSpec, &tc.DisableInlineSpec); err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/config/feature_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
Coschedule: config.CoscheduleDisabled,
EnableCELInWhenExpression: true,
EnableArtifacts: true,
EnableNotices: true,
EnableParamEnum: true,
DisableInlineSpec: "pipeline,pipelinerun,taskrun",
EnableConciseResolverSyntax: true,
Expand Down Expand Up @@ -294,6 +295,9 @@ func TestNewFeatureFlagsConfigMapErrors(t *testing.T) {
}, {
fileName: "feature-flags-invalid-enable-artifacts",
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-artifacts`,
}, {
fileName: "feature-flags-invalid-enable-notices",
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-notices`,
}, {
fileName: "feature-flags-invalid-enable-concise-resolver-syntax",
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-concise-resolver-syntax`,
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/config/testdata/feature-flags-all-flags-set.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ data:
enable-cel-in-whenexpression: "true"
enable-param-enum: "true"
enable-artifacts: "true"
enable-notices: "true"
disable-inline-spec: "pipeline,pipelinerun,taskrun"
enable-concise-resolver-syntax: "true"
enable-kubernetes-sidecar: "true"
Expand Down
21 changes: 21 additions & 0 deletions pkg/apis/config/testdata/feature-flags-invalid-enable-notices.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2026 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: ConfigMap
metadata:
name: feature-flags
namespace: tekton-pipelines
data:
enable-notices: "invalid"
94 changes: 94 additions & 0 deletions pkg/apis/pipeline/v1/notice_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
Copyright 2026 The Tekton Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

const (
maxControllerNotices = 10
maxNoticeMessageLen = 1024
maxNoticeFileLen = 256
)

// NoticeLevel indicates the severity of a notice.
type NoticeLevel string

const (
// NoticeLevelInfo represents an informational message, no action needed.
NoticeLevelInfo NoticeLevel = "info"
// NoticeLevelWarning represents something to address, but not blocking.
NoticeLevelWarning NoticeLevel = "warning"
)

// AllNoticeLevels can be used for NoticeLevel validation.
var AllNoticeLevels = []NoticeLevel{NoticeLevelInfo, NoticeLevelWarning}

// Notice represents a structured message emitted by a controller that does not affect the run's success/failure status.
type Notice struct {
// Level indicates the severity of the notice.
// Valid values: "info", "warning".
// +kubebuilder:validation:Enum=info;warning
Level NoticeLevel `json:"level"`

// Message is the human-readable notice text.
// Maximum length: 1024 characters.
// +kubebuilder:validation:MaxLength=1024
Message string `json:"message"`

// Step is the name of the step that emitted this notice.
// Empty for controller-emitted notices.
// +optional
Step string `json:"step,omitempty"`

// File is the source file path related to this notice.
// Used by VCS integrations to create inline annotations.
// Maximum length: 256 characters.
// +optional
// +kubebuilder:validation:MaxLength=256
File string `json:"file,omitempty"`

// StartLine is the starting line number in the source file (1-based).
// Pointer type so that absence (nil) is distinguishable from line 0.
// +optional
StartLine *int `json:"startLine,omitempty"`
}

// AddControllerNotice appends a bounded, deduplicated controller notice to TaskRun status.
func (trs *TaskRunStatus) AddControllerNotice(notice Notice) {
if notice.Level != NoticeLevelInfo && notice.Level != NoticeLevelWarning {
return
}
notice.Message = truncateString(notice.Message, maxNoticeMessageLen)
notice.File = truncateString(notice.File, maxNoticeFileLen)
notice.Step = ""

for _, existing := range trs.Notices {
if existing.Level == notice.Level && existing.Message == notice.Message {
return
}
}
if len(trs.Notices) >= maxControllerNotices {
return
}
trs.Notices = append(trs.Notices, notice)
}

func truncateString(value string, limit int) string {
runes := []rune(value)
if len(runes) <= limit {
return value
}
return string(runes[:limit])
}
Loading
Loading