You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

534 lines
14 KiB

pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
pipeline: Builder and stage implementation Provides `PipelineBuilder` for reading `.pipeline/config.yaml` and mapping user-defined pipelines, stages, and execution graphs to actual Jenkins Pipeline stage definitions. Provides `Pipeline` class that constructs a "stack" of `PipelineStage` objects from the user-provided configs, each with its own `NodeContext` for binding output values to names and consuming bound values from previous stages. Provides `PipelineStage` that contains core stage step implementations based on the existing `service-pipeline` JJB job definition in `integration/config`. A closure is returned by each stage for passing off to Jenkins Pipeline stage definitions by the builder. Steps have a fixed order within a given stage: build, run, publish, deploy, exports. This allows for concise definition of a stage that performs multiple steps, and deterministic behavior of default configuration that references locally bound output values (e.g. the default configuration of `image:` for an `publish: { type: image }` publish entry is `${.imageID}`, referencing the image built in the current stage's `build` step.) If the user needs to change ordering, they can simply break the stage out into multiple stages. See the `Pipeline` class for currently supported configuration. Note that the aforementioned context system allows for user's to make use of the same value bindings that step implementations use internally. They can also use the `exports` configuration field to bind new values. To illustrate the minimally required configuration, the following would approximate the current `service-pipeline-test-and-publish` JJB job for a project named "foo". pipelines: foo: directory: src/foo stages: - name: test # builds/runs "test" variant - name: candidate build: production publish: image: true deploy: # currently only the "ci" cluster chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true And to illustrate how the "candidate" stage in this example could be expressed as multiple stages using references to the output names that steps bind/export: pipelines: foo: directory: src/foo stages: - name: tested - name: built build: production - name: published publish: image: id: '${built.imageID}' exports: image: '${.imageFullName}:${.imageTag}' - name: staged deploy: image: '${published.image}' chart: https://releases.wikimedia.org/charts/foo-0.0.1.tgz test: true Bug: T210267 Change-Id: I5a41d0d33ed7e9174db6178ab7921f5143296c75
5 years ago
  1. package org.wikimedia.integration
  2. import com.cloudbees.groovy.cps.NonCPS
  3. import static org.wikimedia.integration.Utility.timestampLabel
  4. import org.wikimedia.integration.ExecutionContext
  5. import org.wikimedia.integration.PatchSet
  6. import org.wikimedia.integration.Pipeline
  7. class PipelineStage implements Serializable {
  8. static final String SETUP = 'setup'
  9. static final String TEARDOWN = 'teardown'
  10. static final List STEPS = ['build', 'run', 'publish', 'deploy', 'exports']
  11. Pipeline pipeline
  12. String name
  13. Map config
  14. private def context
  15. /**
  16. * Returns an config based on the given one but with default values
  17. * inserted.
  18. *
  19. * @example Shorthand stage config (providing only a stage name)
  20. * <pre><code>
  21. * def cfg = [name: "foo"]
  22. *
  23. * assert PipelineStage.defaultConfig(cfg) == [
  24. * name: "foo",
  25. * build: '${.stage}', // builds a variant by the same name
  26. * run: [
  27. * image: '${.imageID}', // runs the variant built by this stage
  28. * arguments: [],
  29. * ],
  30. * ]
  31. * </code></pre>
  32. *
  33. * @example Configuring `run: true` means run the variant built by this
  34. * stage
  35. * <pre><code>
  36. * def cfg = [name: "foo", build: "foo", run: true]
  37. *
  38. * assert PipelineStage.defaultConfig(cfg) == [
  39. * name: "foo",
  40. * build: "foo",
  41. * run: [
  42. * image: '${.imageID}', // runs the variant built by this stage
  43. * arguments: [],
  44. * ],
  45. * ]
  46. * </code></pre>
  47. *
  48. * @example Publish image default configuration
  49. * <pre><code>
  50. * def cfg = [image: true]
  51. * def defaults = PipelineStage.defaultConfig(cfg)
  52. *
  53. * // publish.image.id defaults to the previously built image
  54. * assert defaults.publish.image.id == '${.imageID}'
  55. *
  56. * // publish.image.name defaults to the project name
  57. * assert defaults.publish.image.name == '${setup.project}'
  58. *
  59. * // publish.image.tag defaults to {timestamp}-{stage name}
  60. * assert defaults.publish.image.tag == '${setup.timestamp}-${.stage}'
  61. * </code></pre>
  62. */
  63. @NonCPS
  64. static Map defaultConfig(Map cfg) {
  65. Map dcfg
  66. // shorthand with just name is: build and run a variant
  67. if (cfg.size() == 1 && cfg["name"]) {
  68. dcfg = cfg + [
  69. build: '${.stage}',
  70. run: [
  71. image: '${.imageID}',
  72. ]
  73. ]
  74. } else {
  75. dcfg = cfg.clone()
  76. }
  77. if (dcfg.run) {
  78. // run: true means run the built image
  79. if (dcfg.run == true) {
  80. dcfg.run = [
  81. image: '${.imageID}',
  82. ]
  83. } else {
  84. dcfg.run = dcfg.run.clone()
  85. }
  86. // run.image defaults to previously built image
  87. dcfg.run.image = dcfg.run.image ?: '${.imageID}'
  88. // run.arguments defaults to []
  89. dcfg.run.arguments = dcfg.run.arguments ?: []
  90. }
  91. if (dcfg.publish) {
  92. def pcfg = dcfg.publish.clone()
  93. if (pcfg.image) {
  94. if (pcfg.image == true) {
  95. pcfg.image = [:]
  96. } else {
  97. pcfg.image = pcfg.image.clone()
  98. }
  99. // publish.image.id defaults to the previously built image
  100. pcfg.image.id = pcfg.image.id ?: '${.imageID}'
  101. // publish.image.name defaults to the project name
  102. pcfg.image.name = pcfg.image.name ?: "\${${SETUP}.project}"
  103. // publish.image.tag defaults to {timestamp}-{stage name}
  104. pcfg.image.tag = pcfg.image.tag ?: "\${${SETUP}.timestamp}-\${.stage}"
  105. pcfg.image.tags = (pcfg.image.tags ?: []).clone()
  106. }
  107. if (pcfg.files) {
  108. pcfg.files.paths = pcfg.files.paths.clone()
  109. }
  110. dcfg.publish = pcfg
  111. }
  112. if (dcfg.deploy) {
  113. dcfg.deploy = dcfg.deploy.clone()
  114. dcfg.deploy.image = dcfg.deploy.image ?: '${.publishedImage}'
  115. dcfg.deploy.cluster = dcfg.deploy.cluster ?: "ci"
  116. dcfg.deploy.test = dcfg.deploy.test == null ? true : dcfg.deploy.test
  117. }
  118. dcfg
  119. }
  120. PipelineStage(Pipeline pline, String stageName, Map stageConfig, nodeContext) {
  121. pipeline = pline
  122. name = stageName
  123. config = stageConfig
  124. context = nodeContext
  125. }
  126. /**
  127. * Constructs and retruns a closure for this pipeline stage using the given
  128. * Jenkins workflow script object.
  129. */
  130. Closure closure(ws) {
  131. ({
  132. def runner = pipeline.runner(ws)
  133. context["stage"] = name
  134. switch (name) {
  135. case SETUP:
  136. setup(ws, runner)
  137. break
  138. case TEARDOWN:
  139. teardown(ws, runner)
  140. break
  141. default:
  142. ws.echo("running steps in ${pipeline.directory} with config: ${config.inspect()}")
  143. ws.dir(pipeline.directory) {
  144. for (def stageStep in STEPS) {
  145. if (config[stageStep]) {
  146. ws.echo("step: ${stageStep}, config: ${config.inspect()}")
  147. this."${stageStep}"(ws, runner)
  148. }
  149. }
  150. }
  151. }
  152. })
  153. }
  154. /**
  155. * Returns a set of node labels that will be required for this stage to
  156. * function correctly.
  157. */
  158. Set getRequiredNodeLabels() {
  159. def labels = [] as Set
  160. if (config.build || config.run) {
  161. labels.add("blubber")
  162. }
  163. if (config.publish) {
  164. if (config.publish.files) {
  165. labels.add("blubber")
  166. }
  167. if (config.publish.image) {
  168. labels.add("dockerPublish")
  169. }
  170. }
  171. labels
  172. }
  173. /**
  174. * Performs setup steps, checkout out the repo and binding useful values to
  175. * be used by all other stages (default image labels, project identifier,
  176. * timestamp, etc).
  177. *
  178. * <h3>Exports</h3>
  179. * <dl>
  180. * <dt><code>${setup.project}</code></dt>
  181. * <dd>ZUUL_PROJECT parameter value if getting a patchset from Zuul.</dd>
  182. * <dd>Jenkins JOB_NAME value otherwise.</dd>
  183. *
  184. * <dt><code>${setup.timestamp}</code></dt>
  185. * <dd>Timestamp at the start of pipeline execution. Used in image tags, etc.</dd>
  186. *
  187. * <dt><code>${setup.imageLabels}</code></dt>
  188. * <dd>Default set of image labels:
  189. * <code>jenkins.job</code>,
  190. * <code>jenkins.build</code>,
  191. * <code>ci.project</code>,
  192. * <code>ci.pipeline</code>
  193. * </dd>
  194. * </dl>
  195. */
  196. void setup(ws, runner) {
  197. def imageLabels = [
  198. "jenkins.job": ws.env.JOB_NAME,
  199. "jenkins.build": ws.env.BUILD_ID,
  200. ]
  201. if (ws.params.ZUUL_REF) {
  202. def patchset = PatchSet.fromZuul(ws.params)
  203. ws.checkout(patchset.getSCM())
  204. context["project"] = patchset.project.replaceAll('/', '-')
  205. imageLabels["zuul.commit"] = patchset.commit
  206. } else {
  207. ws.checkout(ws.scm)
  208. context["project"] = ws.env.JOB_NAME
  209. }
  210. imageLabels["ci.project"] = context['project']
  211. imageLabels["ci.pipeline"] = pipeline.name
  212. context["timestamp"] = timestampLabel()
  213. context["imageLabels"] = imageLabels
  214. }
  215. /**
  216. * Performs teardown steps, removing images and helm releases, and reporting
  217. * back to Gerrit.
  218. */
  219. void teardown(ws, runner) {
  220. try {
  221. runner.removeImages(context.getAll("imageID").values())
  222. } catch (all) {}
  223. try {
  224. runner.purgeReleases(context.getAll("releaseName").values())
  225. } catch (all) {}
  226. def imageTags = context.getAll("imageTags")
  227. context.getAll("publishedImage").collect { stageName, image ->
  228. try {
  229. runner.reportToGerrit(image, imageTags[stageName] ?: [])
  230. } catch (all) {}
  231. }
  232. }
  233. /**
  234. * Builds the configured Blubber variant.
  235. *
  236. * <h3>Configuration</h3>
  237. * <dl>
  238. * <dt><code>build</code></dt>
  239. * <dd>Blubber variant name</dd>
  240. * </dl>
  241. *
  242. * <h3>Example</h3>
  243. * <pre><code>
  244. * stages:
  245. * - name: candidate
  246. * build: production
  247. * </code></pre>
  248. *
  249. * <h3>Exports</h3>
  250. * <dl>
  251. * <dt><code>${[stage].imageID}</code></dt>
  252. * <dd>Image ID of built image.</dd>
  253. * </dl>
  254. */
  255. void build(ws, runner) {
  256. def imageID = runner.build(context % config.build, context["setup.imageLabels"])
  257. context["imageID"] = imageID
  258. }
  259. /**
  260. * Runs the entry point of a built image variant.
  261. *
  262. * <h3>Configuration</h3>
  263. * <dl>
  264. * <dt><code>run</code></dt>
  265. * <dd>Image to run and entry-point arguments</dd>
  266. * <dd>Specifying <code>run: true</code> expands to
  267. * <code>run: { image: '${.imageID}' }</code>
  268. * (i.e. the image built in this stage)</dd>
  269. * <dd>
  270. * <dl>
  271. * <dt><code>image</code></dt>
  272. * <dd>An image to run</dd>
  273. * <dd>Default: <code>{$.imageID}</code></dd>
  274. *
  275. * <dt><code>arguments</code></dt>
  276. * <dd>Entry-point arguments</dd>
  277. * <dd>Default: <code>[]</code></dd>
  278. * </dl>
  279. * </dd>
  280. * </dl>
  281. *
  282. * <h3>Example</h3>
  283. * <pre><code>
  284. * stages:
  285. * - name: test
  286. * build: test
  287. * run: true
  288. * </code></pre>
  289. *
  290. * <h3>Example</h3>
  291. * <pre><code>
  292. * stages:
  293. * - name: built
  294. * - name: lint
  295. * run:
  296. * image: '${built.imageID}'
  297. * arguments: [lint]
  298. * - name: test
  299. * run:
  300. * image: '${built.imageID}'
  301. * arguments: [test]
  302. * </code></pre>
  303. */
  304. void run(ws, runner) {
  305. runner.run(
  306. context % config.run.image,
  307. config.run.arguments.collect { context % it },
  308. )
  309. }
  310. /**
  311. * Publish artifacts, either files or a built image variant (pushed to the
  312. * WMF Docker registry).
  313. *
  314. * <h3>Configuration</h3>
  315. * <dl>
  316. * <dt><code>publish</code></dt>
  317. * <dd>
  318. * <dl>
  319. * <dt><code>image</code></dt>
  320. * <dd>Publish an to the WMF Docker registry</dd>
  321. * <dd>
  322. * <dl>
  323. * <dt>id</dt>
  324. * <dd>ID of a previously built image variant</dd>
  325. * <dd>Default: <code>${.imageID}</code> (image built in this stage)</dd>
  326. *
  327. * <dt>name</dt>
  328. * <dd>Published name of the image. Note that this base name will be
  329. * prefixed with the globally configured registry/repository name
  330. * before being pushed.</dd>
  331. * <dd>Default: <code>${setup.project}</code> (project identifier;
  332. * see {@link setup()})</dd>
  333. *
  334. * <dt>tag</dt>
  335. * <dd>Primary tag under which the image is published</dd>
  336. * <dd>Default: <code>${setup.timestamp}-${.stage}</code></dd>
  337. *
  338. * <dt>tags</dt>
  339. * <dd>Additional tags under which to publish the image</dd>
  340. * </dl>
  341. * </dd>
  342. * </dl>
  343. * </dd>
  344. * <dd>
  345. * <dl>
  346. * <dt><code>files</code></dt>
  347. * <dd>Extract and save files from a previously built image variant</dd>
  348. * <dd>
  349. * <dl>
  350. * <dt>paths</dt>
  351. * <dd>Globbed file paths resolving any number of files under the
  352. * image's root filesystem</dd>
  353. * </dl>
  354. * </dd>
  355. * </dl>
  356. * </dd>
  357. * </dl>
  358. *
  359. * <h3>Exports</h3>
  360. * <dl>
  361. * <dt><code>${[stage].imageName}</code></dt>
  362. * <dd>Short name under which the image was published</dd>
  363. *
  364. * <dt><code>${[stage].imageFullName}</code></dt>
  365. * <dd>Fully qualified name (registry/repository/imageName) under which the
  366. * image was published</dd>
  367. *
  368. * <dt><code>${[stage].imageTag}</code></dt>
  369. * <dd>Primary tag under which the image was published</dd>
  370. *
  371. * <dt><code>${[stage].publishedImage}</code></dt>
  372. * <dd>Full qualified name and tag (<code>${.imageFullName}:${.imageTag}</code>)</dd>
  373. * </dl>
  374. */
  375. void publish(ws, runner) {
  376. if (config.publish.image) {
  377. def publishImage = config.publish.image
  378. def imageID = context % publishImage.id
  379. def imageName = context % publishImage.name
  380. def imageTags = ([publishImage.tag] + publishImage.tags).collect { context % it }
  381. for (def tag in imageTags) {
  382. runner.registerAs(
  383. imageID,
  384. imageName,
  385. tag,
  386. )
  387. }
  388. context["imageName"] = imageName
  389. context["imageFullName"] = runner.qualifyRegistryPath(imageName)
  390. context["imageTag"] = context % publishImage.tag
  391. context["imageTags"] = imageTags
  392. context["publishedImage"] = context % '${.imageFullName}:${.imageTag}'
  393. }
  394. if (config.publish.files) {
  395. // TODO
  396. }
  397. }
  398. /**
  399. * Deploy a published image to a WMF k8s cluster. (Currently only the "ci"
  400. * cluster is supported for testing.)
  401. *
  402. * <h3>Configuration</h3>
  403. * <dl>
  404. * <dt><code>deploy</code></dt>
  405. * <dd>
  406. * <dl>
  407. * <dt>image</dt>
  408. * <dd>Reference to a previously published image</dd>
  409. * <dd>Default: <code>${.publishedImage}</code> (image published in the
  410. * {@link publish() publish step} of this stage)</dd>
  411. *
  412. * <dt>cluster</dt>
  413. * <dd>Cluster to target</dd>
  414. * <dd>Default: <code>"ci"</code></dd>
  415. * <dd>Currently only "ci" is supported and this configuration is
  416. * effectively ignored</dd>
  417. *
  418. * <dt>chart</dt>
  419. * <dd>URL of Helm chart to use for deployment</dd>
  420. * <dd>Required</dd>
  421. *
  422. * <dt>test</dt>
  423. * <dd>Whether to run <code>helm test</code> against this deployment</dd>
  424. * <dd>Default: <code>true</code></dd>
  425. * </dl>
  426. * </dd>
  427. * </dl>
  428. *
  429. * <h3>Exports</h3>
  430. * <dl>
  431. * <dt><code>${[stage].releaseName}</code></dt>
  432. * <dd>Release name of new deployment</dd>
  433. * </dl>
  434. */
  435. void deploy(ws, runner) {
  436. def release = runner.deployWithChart(
  437. context % config.deploy.chart,
  438. context % config.deploy.image,
  439. context % config.deploy.tag,
  440. )
  441. context["releaseName"] = release
  442. if (config.deploy.test) {
  443. runner.testRelease(release)
  444. }
  445. }
  446. /**
  447. * Binds a number of new values for reference in subsequent stages.
  448. *
  449. * <h3>Configuration</h3>
  450. * <dl>
  451. * <dt><code>exports</code></dt>
  452. * <dd>Name/value pairs for additional exports.</dd>
  453. * </dl>
  454. *
  455. * <h3>Example</h3>
  456. * <pre><code>
  457. * stages:
  458. * - name: candidate
  459. * build: production
  460. * exports:
  461. * image: '${.imageID}'
  462. * tag: '${.imageTag}-my-tag'
  463. * - name: published
  464. * publish:
  465. * image:
  466. * id: '${candidate.image}'
  467. * tags: ['${candidate.tag}']
  468. * </code></pre>
  469. *
  470. * <h3>Exports</h3>
  471. * <dl>
  472. * <dt><code>${[name].[value]}</code></dt>
  473. * <dd>Each configured name/value pair.</dd>
  474. * </dl>
  475. */
  476. void exports(ws, runner) {
  477. config.exports.each { export, value ->
  478. context[export] = context % value
  479. ws.echo "exported ${name}.${export}=${context[export].inspect()}"
  480. }
  481. }
  482. }