diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3949613b..1fe4058d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,7 +33,7 @@ jobs: VALIDATE_MARKDOWN: true jsonschema: - name: Validate examples + name: Validate Examples runs-on: ubuntu-latest steps: @@ -47,3 +47,12 @@ jobs: - name: Validate Examples run: ./tools/verify-examples.sh + + spellcheck: + name: Spellcheck (en_US) + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v3 + - name: Spellcheck + uses: rojopolis/spellcheck-github-actions@0.35.0 diff --git a/.spellcheck-en-custom.txt b/.spellcheck-en-custom.txt new file mode 100644 index 00000000..d340a061 --- /dev/null +++ b/.spellcheck-en-custom.txt @@ -0,0 +1,103 @@ +Auth +BD +CDF +CVE +Gerrit +Github +Gitlab +JSON +KH +KyjITcZXHotdMB +MEYCIQCBT +NGua +NIST +Notational +README +SBOM +SBOMs +SCM +SIG +SRE +Tekton +TestRepo +URI +UUID +XiQlc +american +br +cardpane +cdevent +cdevents +ce +charset +cloudevents +contenttype +customdata +customdatacontenttype +datacontenttype +dataschema +deterministically +dev +emmitted +english +enum +eventdata +fas +fc +geo +href +http +iaas +img +interoperable +jenkins +json +lifecycle +markdownlint +md +modelled +myapp +mybot +mydata +myvalue +namespace +namespaceB +nnnn +notational +observability +param +pdf +pipelinerun +png +pre +quicktime +rfc +rolledback +runtime +sbom +somewherelse +specversion +src +subjectid +taskrun +tekton +testEnv +testcase +testcaserun +testkube +testoutput +testrunreport +testsuite +testsuiterun +ticketURI +toc +typesystem +uri +url +utf +viewUrl +wpaper +xml +ypDXWCjlNKfzTV +yshmiPmp +znnSMNkQIhAJ diff --git a/.spellcheck.yml b/.spellcheck.yml new file mode 100644 index 00000000..cd5a3568 --- /dev/null +++ b/.spellcheck.yml @@ -0,0 +1,37 @@ +matrix: +- name: json + aspell: + lang: en + d: en_US + camel-case: true + mode: url + sources: + - "**/*.json|!.github" + dictionary: + wordlists: + - .spellcheck-en-custom.txt +- name: markdown + aspell: + lang: en + d: en_US + camel-case: true + mode: url + sources: + - "**/*.md" + dictionary: + wordlists: + - .spellcheck-en-custom.txt + pipeline: + - pyspelling.filters.context: + context_visible_first: true + escapes: '\\[\\`~]' + delimiters: + # Ignore multiline content between fences (fences can have 3 or more back ticks) + # ``` + # content + # ``` + - open: '(?s)^(?P *`{3,})$' + close: '^(?P=open)$' + # Ignore text between inline back ticks + - open: '(?P`+)' + close: '(?P=open)' \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..021631ab --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,12 @@ +# Maintainers table +# | Full Name | Company | GitHub | +# |-------------------|:----------:|----------------------------------------------------------------| +# | Emil Bäckmark | Ericsson | [@e-backmark-ericsson](https://github.com/e-backmark-ericsson) | +# | Andrea Frittoli | IBM | [@afrittoli](https://github.com/afrittoli) | +# | Ben Powell | Apple | [@xibz](https://github.com/xibz) | + +# Emeritus maintainers (must be in a comment) +# Note yet + +# Repo maintainers +* @cdevents/spec-maintainers diff --git a/README.md b/README.md index 2f0a1778..5713b99a 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,5 @@ guidelines. ### Governance -The project has been started by the CDF -[SIG Events](https://github.com/cdfoundation/sig-events) and is currently -[governed](https://github.com/cdevents/community/blob/main/governance.md) by a few members of the SIG. +The project has been started by the CDF [SIG Events](https://github.com/cdfoundation/sig-events). +Its governance is [documented in the community repository](https://github.com/cdevents/community/blob/main/governance.md). diff --git a/cloudevents-binding.md b/cloudevents-binding.md index b3af8650..886c2e15 100644 --- a/cloudevents-binding.md +++ b/cloudevents-binding.md @@ -92,7 +92,7 @@ Full example of a CDEvents transported through a CloudEvent in HTTP *binary* mod POST /sink HTTP/1.1 Host: cdevents.example.com ce-specversion: 1.0 -ce-type: dev.cdevents.taskrun.started.0.1-draft +ce-type: dev.cdevents.taskrun.started.0.1.1 ce-time: 2018-04-05T17:31:00Z ce-id: A234-1234-1234 ce-source: /staging/tekton/ @@ -102,10 +102,10 @@ Content-Length: nnnn { "context": { - "version": "0.4.0-draft", + "version": "0.3.0", "id" : "A234-1234-1234", "source" : "/staging/tekton/", - "type" : "dev.cdevents.taskrun.started", + "type" : "dev.cdevents.taskrun.started.0.1.1", "timestamp" : "2018-04-05T17:31:00Z", } "subject" : { diff --git a/continuous-integration.md b/continuous-integration.md index a487c973..06ccc86d 100644 --- a/continuous-integration.md +++ b/continuous-integration.md @@ -10,16 +10,16 @@ description: > --> # Continuous Integration Events -Continuous Integration (CI) events include the subject and predicates related to CI activities such as building software, producing artifacts and running tests. +Continuous Integration (CI) events include the subject and predicates related to CI activities such as [building software](#build), producing [artifacts](#artifact) and [running tests](./testing-events.md). ## Subjects -This specification defines three subjects in this stage: `builds`, `artifacts` and `tests`. Events associated with these subjects are typically generated either by a CI system that orchestrates the process or by a specific build or test tool directly. Some artifact events may be generated by the system that stores the artifact as well. +This specification defines two subjects in this stage: `build` and `artifact`. Events associated with these subjects are typically generated either by a CI system that orchestrates the process or by a specific build or test tool directly. Some artifact events may be generated by the system that stores the artifact as well. | Subject | Description | Predicates | |---------|-------------|------------| | [`build`](#build) | A software build | [`queued`](#build-queued), [`started`](#build-started), [`finished`](#build-finished)| -| [`artifact`](#artifact) | An artifact produced by a build | [`packaged`](#artifact-packaged), [`published`](#artifact-published), [`signed`](#artifact-signed)| +| [`artifact`](#artifact) | An artifact produced by a build | [`packaged`](#artifact-packaged), [`signed`](#artifact-signed), [`published`](#artifact-published), [`downloaded`](#artifact-downloaded)| > `testCase`/`testSuite` events have moved to their own top-level bucket [Testing Events](testing-events.md) @@ -27,7 +27,7 @@ This specification defines three subjects in this stage: `builds`, `artifacts` a A `build` is a process that uses a recipe to produce an artifact from source code. -__Note:__ The data model for `builds`, apart from `id` and `source`, only includes the identifier of the artifact produced by the build. The inputs to the build process are not specified yet. +__Note:__ The data model for `build`, apart from `id` and `source`, only includes the identifier of the artifact produced by the build. The inputs to the build process are not specified yet. | Field | Type | Description | Examples | |-------|------|-------------|----------| @@ -47,6 +47,8 @@ An `artifact` is usually produced as output of a build process. Events need to b | type | `String` | See [type](spec.md#type-subject) | `artifact` | | change | `object` | The change (tag, commit, revision) of the repository which was used to build the artifact" | `{"id": "527d4a1aca5e8d0df24813df5ad65d049fc8d312", "source": "my-git.example/an-org/a-repo"}`, `{"id": "feature1234", "source": "my-git.example/an-org/a-repo"}` | | signature | `string` | The signature of the artifact | `MEYCIQCBT8U5ypDXWCjlNKfzTV4KH516/SK13NZSh8znnSMNkQIhAJ3XiQlc9PM1KyjITcZXHotdMB+J3NGua5T/yshmiPmp` | +| sbom | [`sbom`](#sbom) | The Software Bill of Material (SBOM) associated with the artifact | `{"uri": "https://sbom.storage.service/my-projects/3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427.sbom"}` | +| user | `string` | The user who performed the predicate on the artifact registry. [^user] | `mybot-myapp` | ## Events @@ -96,8 +98,9 @@ This event represents a Build task that has finished. This event will eventually ### [`artifact packaged`](examples/artifact_packaged.json) The event represents an artifact that has been packaged for distribution; this artifact is now versioned with a fixed version. +This event is usually produced by the build system. If an SBOM URI is available at this stage, it should be included. -- Event Type: __`dev.cdevents.artifact.packaged.0.1.1`__ +- Event Type: __`dev.cdevents.artifact.packaged.0.2.0-draft`__ - Predicate: packaged - Subject: [`artifact`](#artifact) @@ -107,12 +110,30 @@ The event represents an artifact that has been packaged for distribution; this a | source | `URI-Reference` | See [source](spec.md#source-subject) | | | | type | `String` | See [type](spec.md#type-subject) | `artifact` | | | change | `object` | The change (tag, commit, revision) of the repository which was used to build the artifact" | `{"id": "527d4a1aca5e8d0df24813df5ad65d049fc8d312", "source": "my-git.example/an-org/a-repo"}`, `{"id": "feature1234", "source": "my-git.example/an-org/a-repo"}` | ✅ | +| sbom | [`sbom`](#sbom) | The Software Bill of Material (SBOM) associated with the artifact | `{"uri": "https://sbom.storage.service/my-projects/3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427.sbom"}` | | + +### [`artifact signed`](examples/artifact_signed.json) + +The event represents an artifact that has been signed. The signature is included in the events itself. +An artifact may be signed after it has been packaged or sometimes after it has published, depending on the tooling being used and the type of artifact. The `artifact signed` event is typically produced by the CI or build system. + +- Event Type: __`dev.cdevents.artifact.signed.0.1.0`__ +- Predicate: signed +- Subject: [`artifact`](#artifact) + +| Field | Type | Description | Examples | Required | +|-------|------|-------------|----------|----------------------------| +| id | `Purl` | See [id](spec.md#id-subject) | `pkg:oci/myapp@sha256%3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427?repository_url=mycr.io/myapp`, `pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c` | ✅ | +| source | `URI-Reference` | See [source](spec.md#source-subject) | | | +| type | `String` | See [type](spec.md#type-subject) | `artifact` | | +| signature | `string` | The signature of the artifact | `MEYCIQCBT8U5ypDXWCjlNKfzTV4KH516/SK13NZSh8znnSMNkQIhAJ3XiQlc9PM1KyjITcZXHotdMB+J3NGua5T/yshmiPmp` | ✅ | ### [`artifact published`](examples/artifact_published.json) The event represents an artifact that has been published and it can be advertised for others to use. +The `artifact published` event is typically produced by the artifact registry, but it may also be produced by the build system. -- Event Type: __`dev.cdevents.artifact.published.0.1.1`__ +- Event Type: __`dev.cdevents.artifact.published.0.2.0-draft`__ - Predicate: published - Subject: [`artifact`](#artifact) @@ -121,14 +142,15 @@ The event represents an artifact that has been published and it can be advertise | id | `Purl` | See [id](spec.md#id-subject) | `pkg:oci/myapp@sha256%3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427?repository_url=mycr.io/myapp`, `pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c` | ✅ | | source | `URI-Reference` | See [source](spec.md#source-subject) | | | | type | `String` | See [type](spec.md#type-subject) | `artifact` | | +| user | `String` | The user who published to the artifact registry. [^user] | `mybot-myapp` | | -### [`artifact signed`](examples/artifact_signed.json) +### [`artifact downloaded`](examples/artifact_downloaded.json) -The event represents an artifact that has been signed. The signature is included in the events itself. -An artifact may be signed after it has been packaged or sometimes after it has published, depending on the tooling being used and the type of artifact. +The event represents an artifact that has been downloaded from the registry. +The `artifact downloaded` event is preferably produced by the artifact registry. -- Event Type: __`dev.cdevents.artifact.signed.0.1.0`__ -- Predicate: signed +- Event Type: __`dev.cdevents.artifact.downloaded.0.1.0-draft`__ +- Predicate: downloaded - Subject: [`artifact`](#artifact) | Field | Type | Description | Examples | Required | @@ -136,4 +158,32 @@ An artifact may be signed after it has been packaged or sometimes after it has p | id | `Purl` | See [id](spec.md#id-subject) | `pkg:oci/myapp@sha256%3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427?repository_url=mycr.io/myapp`, `pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c` | ✅ | | source | `URI-Reference` | See [source](spec.md#source-subject) | | | | type | `String` | See [type](spec.md#type-subject) | `artifact` | | -| signature | `string` | The signature of the artifact | `MEYCIQCBT8U5ypDXWCjlNKfzTV4KH516/SK13NZSh8znnSMNkQIhAJ3XiQlc9PM1KyjITcZXHotdMB+J3NGua5T/yshmiPmp` | ✅ | +| user | `String` | The user who downloaded from the artifact registry. [^user] | `mybot-myapp` | | + +### [`artifact deleted`](examples/artifact_deleted.json) + +The event represents an artifact that has been deleted from an artifact registry. +The `artifact deleted` event is preferably produced by the artifact registry. + +- Event Type: __`dev.cdevents.artifact.deleted.0.1.0-draft`__ +- Predicate: deleted +- Subject: [`artifact`](#artifact) + +| Field | Type | Description | Examples | Required | +|-------|------|-------------|----------|----------------------------| +| id | `Purl` | See [id](spec.md#id-subject) | `pkg:oci/myapp@sha256%3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427?repository_url=mycr.io/myapp`, `pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c` | ✅ | +| source | `URI-Reference` | See [source](spec.md#source-subject) | | | +| type | `String` | See [type](spec.md#type-subject) | `artifact` | | +| user | `String` | The user who deleted from the artifact registry. [^user] | `mybot-myapp` | | + +[^user]: The actual format of `user` depends on the specific registry and authentication method used. If access to the artifact registry is obtained through a long lived token, this could be the name or description associated with the token at provisioning time. In case of an anonymous read operations, the user depends on the protocol used, a typically useful value would be the IP address of the client performing the read. + +## Objects + +### `sbom` + +Several events reference a Software Bill of Materials (SBOM). In CDEvents SBOMs are represented via the `sbom` object, which is a reference to an externally hosted SBOM. The `sbom` object includes a single `uri` field, and is defined as an object to allow for more fields to be added in a backwards compatible manner in future. + +| Field | Type | Description | Examples | +|-------|------|-------------|----------| +| `uri` | `URI-Reference` | Link to an externally hosted SBOM. | `https://sbom.storage.service/my-projects/3A0b31b1c02ff458ad9b7b81cbdf8f028bd54699fa151f221d1e8de6817db93427.sbom` | \ No newline at end of file diff --git a/core.md b/core.md index 33be5a5f..116d66e0 100644 --- a/core.md +++ b/core.md @@ -16,7 +16,7 @@ Core events are at the lower level of abstraction in the dictionary: they descri ## Subjects In the context of Continuous Delivery, a *pipeline* is the definition of a set of *tasks* that needs to be performed to build, test, package, release and deploy software artifacts. -The definition of *pipelines* and *tasks* is an authoring process, and has no event associated to it. CDEvents identifies two [*subjects*](./spec/README.md), [`pipelineRun`](#pipelinerun) and [`taskRun`](#taskrun), which are the runtime counterparts of *pipelines* and *tasks*. +The definition of *pipelines* and *tasks* is an authoring process, and has no event associated to it. CDEvents identifies two [*subjects*](spec.md#subject), [`pipelineRun`](#pipelinerun) and [`taskRun`](#taskrun), which are the runtime counterparts of *pipelines* and *tasks*. | Subject | Description | Predicates | |---------|-------------|------------| @@ -38,7 +38,7 @@ track the build and release progress on a particular software artifact. | pipelineName | `String` | The name of the pipeline | `MyPipeline`, `Unit tests for my repo` | | outcome | `String` | outcome of a finished `pipelineRun` | `success`, `error` or `failure`| | url | `URI` | url to the `pipelineRun` | `https://dashboard.org/namespace/pipelinerun-1234`, `https://api.cdsystem.com/namespace/pipelinerun-1234` | -| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `pipelineRun cancelled by user`, `Unit tests failed`| +| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `pipelineRun canceled by user`, `Unit tests failed`| ### `taskRun` @@ -58,7 +58,7 @@ associated, in which case it is acceptable to generate only taskRun events. | pipelineRun | `Object` ([`pipelineRun`](#pipelinerun)) | The `pipelineRun` that this `taskRun` belongs to. | `{"id": "namespace/pipelinerun-1234"}`| | outcome | `String` | outcome of a finished `taskRun` | `success`, `error` or `failure`| | url | `URI` | url to the `taskRun` | `https://dashboard.org/namespace/taskrun-1234`, `https://api.cdsystem.com/namespace/taskrun-1234` | -| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `taskRun cancelled by user`, `Unit tests failed`| +| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `taskRun canceled by user`, `Unit tests failed`| ## Events @@ -112,7 +112,7 @@ A pipelineRun has finished, successfully or not. | pipelineName | `String` | The name of the pipeline | `MyPipeline`, `Unit tests for my repo` | | | url | `URI` | url to the `pipelineRun` | `https://dashboard.org/namespace/pipelinerun-1234`, `https://api.cdsystem.com/namespace/pipelinerun-1234` | | | outcome | `String (enum)` | outcome of a finished `pipelineRun` | `success`, `error` or `failure`| | -| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `pipelineRun cancelled by user`, `Unit tests failed`| | +| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `pipelineRun canceled by user`, `Unit tests failed`| | ### [`taskRun Started`](examples/taskrun_started.json) @@ -148,4 +148,4 @@ A taskRun has finished, successfully or not. | pipelineRun | `Object` ([`pipelineRun`](#pipelinerun)) | The `pipelineRun` that this `taskRun` belongs to. | `{"id": "namespace/pipelinerun-1234"}`| | | url | `URI` | url to the `taskRun` | `https://dashboard.org/namespace/taskrun-1234`, `https://api.cdsystem.com/namespace/taskrun-1234` | | | outcome | `String (enum)` | outcome of a finished `taskRun` | `success`, `error` or `failure`| | -| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `taskRun cancelled by user`, `Unit tests failed`| | +| errors | `String` | In case of error or failed pipeline, provides details about the failure | `Invalid input param 123`, `Timeout during execution`, `taskRun canceled by user`, `Unit tests failed`| | diff --git a/examples/artifact_deleted.json b/examples/artifact_deleted.json new file mode 100644 index 00000000..a4536829 --- /dev/null +++ b/examples/artifact_deleted.json @@ -0,0 +1,17 @@ +{ + "context": { + "version": "0.4.0-draft", + "id": "271069a8-fc18-44f1-b38f-9d70a1695819", + "source": "/event/source/123", + "type": "dev.cdevents.artifact.deleted.0.1.0-draft", + "timestamp": "2023-03-20T14:27:05.315384Z" + }, + "subject": { + "id": "pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c", + "source": "/event/source/123", + "type": "artifact", + "content": { + "user": "mybot-myapp" + } + } +} diff --git a/examples/artifact_downloaded.json b/examples/artifact_downloaded.json new file mode 100644 index 00000000..94d0f718 --- /dev/null +++ b/examples/artifact_downloaded.json @@ -0,0 +1,17 @@ +{ + "context": { + "version": "0.4.0-draft", + "id": "271069a8-fc18-44f1-b38f-9d70a1695819", + "source": "/event/source/123", + "type": "dev.cdevents.artifact.downloaded.0.1.0-draft", + "timestamp": "2023-03-20T14:27:05.315384Z" + }, + "subject": { + "id": "pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c", + "source": "/event/source/123", + "type": "artifact", + "content": { + "user": "mybot-myapp" + } + } +} diff --git a/examples/artifact_packaged.json b/examples/artifact_packaged.json index c88744fa..238e20bb 100644 --- a/examples/artifact_packaged.json +++ b/examples/artifact_packaged.json @@ -3,7 +3,7 @@ "version": "0.4.0-draft", "id": "271069a8-fc18-44f1-b38f-9d70a1695819", "source": "/event/source/123", - "type": "dev.cdevents.artifact.packaged.0.1.1", + "type": "dev.cdevents.artifact.packaged.0.2.0-draft", "timestamp": "2023-03-20T14:27:05.315384Z" }, "subject": { @@ -14,6 +14,9 @@ "change": { "id": "myChange123", "source": "my-git.example/an-org/a-repo" + }, + "sbom": { + "uri": "https://sbom.repo/myorg/234fd47e07d1004f0aed9c.sbom" } } } diff --git a/examples/artifact_published.json b/examples/artifact_published.json index 43d94b74..462a623f 100644 --- a/examples/artifact_published.json +++ b/examples/artifact_published.json @@ -3,13 +3,18 @@ "version": "0.4.0-draft", "id": "271069a8-fc18-44f1-b38f-9d70a1695819", "source": "/event/source/123", - "type": "dev.cdevents.artifact.published.0.1.1", + "type": "dev.cdevents.artifact.published.0.2.0-draft", "timestamp": "2023-03-20T14:27:05.315384Z" }, "subject": { "id": "pkg:golang/mygit.com/myorg/myapp@234fd47e07d1004f0aed9c", "source": "/event/source/123", "type": "artifact", - "content": {} + "content": { + "sbom": { + "uri": "https://sbom.repo/myorg/234fd47e07d1004f0aed9c.sbom" + }, + "user": "mybot-myapp" + } } } diff --git a/schemas/artifactdeleted.json b/schemas/artifactdeleted.json new file mode 100644 index 00000000..926333bf --- /dev/null +++ b/schemas/artifactdeleted.json @@ -0,0 +1,101 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdevents.dev/0.4.0-draft/schema/artifact-deleted-event", + "properties": { + "context": { + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "enum": [ + "dev.cdevents.artifact.deleted.0.1.0-draft" + ], + "default": "dev.cdevents.artifact.deleted.0.1.0-draft" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "version", + "id", + "source", + "type", + "timestamp" + ] + }, + "subject": { + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "minLength": 1, + "enum": [ + "artifact" + ], + "default": "artifact" + }, + "content": { + "properties": { + "user": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false, + "type": "object" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "type", + "content" + ] + }, + "customData": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "string", + "contentEncoding": "base64" + } + ] + }, + "customDataContentType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "context", + "subject" + ] +} \ No newline at end of file diff --git a/schemas/artifactdownloaded.json b/schemas/artifactdownloaded.json new file mode 100644 index 00000000..b0d97a6f --- /dev/null +++ b/schemas/artifactdownloaded.json @@ -0,0 +1,101 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cdevents.dev/0.4.0-draft/schema/artifact-downloaded-event", + "properties": { + "context": { + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "enum": [ + "dev.cdevents.artifact.downloaded.0.1.0-draft" + ], + "default": "dev.cdevents.artifact.downloaded.0.1.0-draft" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "version", + "id", + "source", + "type", + "timestamp" + ] + }, + "subject": { + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "source": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + }, + "type": { + "type": "string", + "minLength": 1, + "enum": [ + "artifact" + ], + "default": "artifact" + }, + "content": { + "properties": { + "user": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false, + "type": "object" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "type", + "content" + ] + }, + "customData": { + "oneOf": [ + { + "type": "object" + }, + { + "type": "string", + "contentEncoding": "base64" + } + ] + }, + "customDataContentType": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "context", + "subject" + ] +} \ No newline at end of file diff --git a/schemas/artifactpackaged.json b/schemas/artifactpackaged.json index 27aca12b..e293f617 100644 --- a/schemas/artifactpackaged.json +++ b/schemas/artifactpackaged.json @@ -20,9 +20,9 @@ "type": { "type": "string", "enum": [ - "dev.cdevents.artifact.packaged.0.1.1" + "dev.cdevents.artifact.packaged.0.2.0-draft" ], - "default": "dev.cdevents.artifact.packaged.0.1.1" + "default": "dev.cdevents.artifact.packaged.0.2.0-draft" }, "timestamp": { "type": "string", @@ -77,6 +77,20 @@ "required": [ "id" ] + }, + "sbom": { + "properties": { + "uri": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "uri" + ] } }, "additionalProperties": false, diff --git a/schemas/artifactpublished.json b/schemas/artifactpublished.json index fc56f008..c66081c0 100644 --- a/schemas/artifactpublished.json +++ b/schemas/artifactpublished.json @@ -20,9 +20,9 @@ "type": { "type": "string", "enum": [ - "dev.cdevents.artifact.published.0.1.1" + "dev.cdevents.artifact.published.0.2.0-draft" ], - "default": "dev.cdevents.artifact.published.0.1.1" + "default": "dev.cdevents.artifact.published.0.2.0-draft" }, "timestamp": { "type": "string", @@ -59,7 +59,26 @@ "default": "artifact" }, "content": { - "properties": {}, + "properties": { + "sbom": { + "properties": { + "uri": { + "type": "string", + "minLength": 1, + "format": "uri-reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "uri" + ] + }, + "user": { + "type": "string", + "minLength": 1 + } + }, "additionalProperties": false, "type": "object" } diff --git a/source-code-version-control.md b/source-code-version-control.md index f164c9c8..f224c348 100644 --- a/source-code-version-control.md +++ b/source-code-version-control.md @@ -14,7 +14,7 @@ Source Code Control events includes the subjects and predicates related to chang ## Subjects -This specification defines two subjects in this stage: `repository` and `change`. Events associated with these subjects are triggered by actions performed by software developers or bots that provide useful automation for software developers. +This specification defines three subjects in this stage: `repository`, `branch`, and `change`. Events associated with these subjects are triggered by actions performed by software developers or bots that provide useful automation for software developers. | Subject | Description | Predicates | |---------|-------------|------------| diff --git a/spec.md b/spec.md index 0c748c4e..6f554577 100644 --- a/spec.md +++ b/spec.md @@ -82,6 +82,11 @@ The specification is structured in two main parts: For an introduction see the [CDEvents README](README.md) and for more background information please see our [CDEvents primer](https://cdevents.dev/docs/primer/). +## Spelling + +CDEvents adopt american english ("en_US") as dictionary for spelling both in the +specification as well as in the documentation. + ## Notations and Terminology ### Notational Conventions @@ -492,8 +497,11 @@ dedicated document in the spec: emitted by changes in source code or by the creation, modification or deletion of new repositories that hold source code. - __[Continuous Integration](continuous-integration.md)__: - includes events related to building, testings, packaging and releasing - software artifacts, usually binaries. + includes events related to building software artifacts and packaging, releasing + and managing software artifacts. +- __[Testing](testing.md)__: + includes events related to testing. Sometimes part of continuous + integration, testing may take place in different stages of the workflow. - __[Continuous Deployment](continuous-deployment.md)__: include events related with environments where the artifacts produced by the integration pipelines actually run. These are usually services running in a diff --git a/tools/verify-examples.sh b/tools/verify-examples.sh index d7735363..522acbb6 100755 --- a/tools/verify-examples.sh +++ b/tools/verify-examples.sh @@ -44,20 +44,21 @@ go install github.com/neilpa/yajsv@v1.4.1 # - examples are subject_predicate.json # - schemas are subjectpredicate.json num_failed=0 -num_examples=$(ls "$EXAMPLES_FOLDER" | wc -l | awk '{ print $1 }') -for example in $(ls "$EXAMPLES_FOLDER"); do - SUBJECT_PREDICATE=$(basename $example .json) +num_examples=$(find "${EXAMPLES_FOLDER}" -type f -name '*json' | wc -l | awk '{ print $1 }') +for example in $(find "${EXAMPLES_FOLDER}" -type f -name '*json'); do + EXAMPLE_FILE=$(basename ${example}) + SUBJECT_PREDICATE=$(basename $EXAMPLE_FILE .json) splitArray=(${SUBJECT_PREDICATE//_/ }) SUBJECT=${splitArray[0]} PREDICATE=${splitArray[1]} - EXAMPLE_FILE=${EXAMPLES_FOLDER}/${example} SCHEMA_FILE=${SCHEMAS_FOLDER}/${SUBJECT}${PREDICATE}.json echo "==> $SUBJECT $PREDICATE" - yajsv -s "$SCHEMA_FILE" "$EXAMPLE_FILE" || num_failed=$(( num_failed + 1 )) + echo yajsv -s "$SCHEMA_FILE" "$example" + yajsv -s "$SCHEMA_FILE" "$example" || num_failed=$(( num_failed + 1 )) echo done if [ $num_failed -gt 0 ]; then echo "${num_failed} out of ${num_examples} examples failed validation" fi -exit $num_failed \ No newline at end of file +exit $num_failed