diff --git a/task/asciidoctor/0.2/README.md b/task/asciidoctor/0.2/README.md new file mode 100644 index 0000000000..e17287b75a --- /dev/null +++ b/task/asciidoctor/0.2/README.md @@ -0,0 +1,102 @@ +# Asciidoctor + +Tekton Task for Asciidoctor https://asciidoctor.org + +Asciidoctor is a fast, open source, Ruby-based text processor for parsing AsciiDoc into a document model and converting it to output formats such as HTML 5, DocBook 5, manual pages, PDF, EPUB 3, and other formats. + +The resulting document can be sent by email, uploaded to the artifact repository, etc. through other tasks. + +## Install the Task +``` +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/asciidoctor/0.2/asciidoctor.yaml +``` + +## Pre-requisite +Install git-clone task from catalog +``` +https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.3/git-clone.yaml +``` + +## Workspaces +* **source** : A Workspace containing your source directory. + +## Parameters +* **ASCIIDOC_CMD**: Default ```asciidoctor-pdf```. Command to convert AsciiDoc files : + * **asciidoctor**: Basic CLI [Info](https://docs.asciidoctor.org/asciidoctor/latest/cli/) + * **asciidoctor-pdf**: Converter from AsciiDoc to PDF [Info](https://asciidoctor.org/docs/asciidoctor-pdf/) + * **asciidoctor-epub3**: Converter from AsciiDoc to EPUB3 and KF8/MOBI [Info](https://docs.asciidoctor.org/epub3-converter/latest/) + * **asciidoctor-confluence**: Parse asciidoc files them using Asciidoctor and push the result into Confluence [Info](https://github.com/asciidoctor/asciidoctor-confluence) + * **asciidoctor-fb2**: Converter documents directly to the FB2 e-book format [Info](https://github.com/asciidoctor/asciidoctor-fb2) + * **asciidoctor-pdf-optimize**: By default, Asciidoctor PDF does not optimize the PDF it generates or compress its streams. [Info](https://github.com/asciidoctor/asciidoctor-pdf#optimizing-the-generated-pdf) + * **asciidoctor-revealjs**: Converter for Asciidoctor and Asciidoctor.js that transforms an AsciiDoc document into an HTML5 presentation designed to be executed by the reveal.js presentation framework. [Info](https://docs.asciidoctor.org/reveal.js-converter/latest/) +* **ADOC_PATH** : The .adoc file path. Default ```./Readme.md```. +* **ASCIIDOC_ARGS**: The Arguments to be passed to Asciidoctor command, for example ```-a lang=es -a draft=yes```. Each binary can have different arguments, see the information of each binary of **ASCIIDOC_CMD**. +* **ASCIIDOC_IMAGE**: Asciidoctor image to be used. default ```docker.io/asciidoctor/docker-asciidoctor:1.16```. + +## Platforms + +The Task can be run on `linux/amd64` platform. + +## Usage + +In the [tests](../0.1/tests/run.yaml), folder there is an example of the execution of the task, a [PVC](../0.1/tests/pvc.yaml) is used. + +## Sample asciidoc code and output + +The complete code for the example is in the [repository](https://github.com/jandradap/tekton-asciidoctor-demo). + +**Asciidoc code:** +```md +== Title 2 + +Crystalline XML tags relentlessly bombarded the theater. + +.XML tags +[source,xml] +---- + + + Lazarus + het Draeke + + +---- + +Despite the assault, we continued our pursuit to draft a DefOps{empty}footnote:defops[] plan. + +.DefOps Plan +==== +Click btn:[Download Zip] to download the defensive operation plan bundle. + +OMG! +Somebody please save us now! +I want my mum -- and an extra-large double macchiato, please. +==== + +Unfortunaly, Lazarus and I had both come to the conclusion that we weren't going to get out of +this without corrupted hardrives if we didn't locate caffeine within the next few hours. + +=== Subitle 2 + +This potion for a sample document contains the following ingredients, which are listed in a +very random, chaotically nested order. + +.Ingredients for Potion that Demystifies Documents +* all the headings +** syntax highlighted source code +*** non-syntax highlighted source code or just a listing block +* quote block +** verse block +*** table with some cell formatting +**** sequential paragraphs +***** admonition blocks, but use them sparingly +*** bullet list with nesting +** numbered list with nesting +** definition list +*** sidebar +``` + +**Output:** + +![Title page](https://raw.githubusercontent.com/jandradap/tekton-asciidoctor-demo/main/images/pag1.png) +![Random page](https://raw.githubusercontent.com/jandradap/tekton-asciidoctor-demo/main/images/pag3.png) diff --git a/task/asciidoctor/0.2/asciidoctor.yaml b/task/asciidoctor/0.2/asciidoctor.yaml new file mode 100644 index 0000000000..a77b509a3a --- /dev/null +++ b/task/asciidoctor/0.2/asciidoctor.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + annotations: + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/categories: Publishing + tekton.dev/tags: 'asciidoctor, Publishing, PDF, EPUB' + tekton.dev/displayName: "asciidoctor text processor" + tekton.dev/platforms: "linux/amd64" + name: asciidoctor + labels: + app.kubernetes.io/version: "0.2" +spec: + description: >- + Asciidoctor is a fast, open source, Ruby-based text processor + for parsing AsciiDoc into a document model and converting it + to output formats such as HTML 5, DocBook 5, manual pages, PDF, + EPUB 3, and other formats. + params: + - name: ASCIIDOC_CMD + description: Command to convert AsciiDoc files asciidoctor, asciidoctor-pdf, asciidoctor-epub3 + type: string + default: 'asciidoctor-pdf' + - name: ADOC_PATH + description: The .adoc file path. + type: string + default: './Readme.adoc' + - name: ASCIIDOC_ARGS + description: The Arguments to be passed to Asciidoctor command. + type: string + - name: ASCIIDOC_IMAGE + default: docker.io/asciidoctor/docker-asciidoctor:1.16@sha256:36117d900e9365923dcf1d79c99eb82192c3d1b81ca1bb077e3373f722532e05 + description: Asciidoctor image to be used + steps: + - name: asciidoctor + image: $(params.ASCIIDOC_IMAGE) + workingDir: $(workspaces.source.path) + script: | + #!/usr/bin/env sh + set -e + ls -lh + "${ASCIIDOC_CMD}" "${ASCIIDOC_ARGS}" "${ADOC_PATH}" + env: + - name: ASCIIDOC_CMD + value: "$(params.ASCIIDOC_CMD)" + - name: ADOC_PATH + value: "$(params.ADOC_PATH)" + - name: ASCIIDOC_ARGS + value: "$(params.ASCIIDOC_ARGS)" + workspaces: + - description: A workspace that contains fetched git repo. + name: source diff --git a/task/asciidoctor/0.2/tests/pre-apply-task-hook.sh b/task/asciidoctor/0.2/tests/pre-apply-task-hook.sh new file mode 100644 index 0000000000..149d02a6c3 --- /dev/null +++ b/task/asciidoctor/0.2/tests/pre-apply-task-hook.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Add git-clone +add_task git-clone latest \ No newline at end of file diff --git a/task/asciidoctor/0.2/tests/pvc.yaml b/task/asciidoctor/0.2/tests/pvc.yaml new file mode 100644 index 0000000000..5e07e072db --- /dev/null +++ b/task/asciidoctor/0.2/tests/pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: asciidoctor-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi \ No newline at end of file diff --git a/task/asciidoctor/0.2/tests/run.yaml b/task/asciidoctor/0.2/tests/run.yaml new file mode 100644 index 0000000000..e42d12dc4b --- /dev/null +++ b/task/asciidoctor/0.2/tests/run.yaml @@ -0,0 +1,72 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: asciidoctor-pipeline +spec: + params: + - name: repository + type: string + - name: ASCIIDOC_CMD + type: string + - name: ADOC_PATH + type: string + - name: ASCIIDOC_ARGS + type: string + - name: ASCIIDOC_IMAGE + type: string + workspaces: + - name: source + tasks: + - name: clone-git-repo + workspaces: + - name: output + workspace: source + taskRef: + name: git-clone + params: + - name: url + value: $(params.repository) + - name: deleteExisting + value: "true" + - name: asciidoctor + taskRef: + kind: Task + name: asciidoctor + runAfter: + - clone-git-repo + workspaces: + - name: source + workspace: source + params: + - name: ASCIIDOC_CMD + value: $(params.ASCIIDOC_CMD) + - name: ADOC_PATH + value: $(params.ADOC_PATH) + - name: ASCIIDOC_ARGS + value: $(params.ASCIIDOC_ARGS) + - name: ASCIIDOC_IMAGE + value: $(params.ASCIIDOC_IMAGE) +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: asciidoctor-pipelinerun +spec: + pipelineRef: + name: asciidoctor-pipeline + params: + - name: repository + value: https://github.com/jandradap/tekton-asciidoctor-demo.git + - name: ASCIIDOC_CMD + value: 'asciidoctor-pdf' + - name: ADOC_PATH + value: './Readme.adoc' + - name: ASCIIDOC_ARGS + value: '-a lang=es' + - name: ASCIIDOC_IMAGE + value: docker.io/asciidoctor/docker-asciidoctor:1.16@sha256:36117d900e9365923dcf1d79c99eb82192c3d1b81ca1bb077e3373f722532e05 + workspaces: + - name: source + persistentVolumeClaim: + claimName: asciidoctor-pvc \ No newline at end of file diff --git a/task/cloudevent/0.2/README.md b/task/cloudevent/0.2/README.md new file mode 100644 index 0000000000..3568242420 --- /dev/null +++ b/task/cloudevent/0.2/README.md @@ -0,0 +1,35 @@ +# CloudEvent Task + +Task to send a single CloudEvent to a specified sink. + +## Parameters + +* **sink**: Sink is the uri to send the event to + +* **eventID**: Event ID to send + +* **eventType**: The event type to send + + _default_: "tekton.cloudevent.message" + +* **source**: Source to be set in the Cloudevent metadata. + + _default_: "cloudevent-catalog-task" + +* **data**: Data payload to deliver + + _default_: ""` + +## Development + +The `ko` tool is required to update the task.yaml - see these [installation instructions](https://github.com/google/ko#installation). + +Once you have ko, you can build the binary and resolve the task yaml into installable yaml. + +`ko resolve -f config/task.yaml > cloudevent.yaml` + +The go import path will be replaced in the yaml by the built container. + +## Platforms + +The Task can be run on `linux/amd64` platform. \ No newline at end of file diff --git a/task/cloudevent/0.2/cloudevent.yaml b/task/cloudevent/0.2/cloudevent.yaml new file mode 100644 index 0000000000..47538ccd38 --- /dev/null +++ b/task/cloudevent/0.2/cloudevent.yaml @@ -0,0 +1,43 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: cloudevent + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/categories: Networking + tekton.dev/tags: cloud + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + This Task send a single CloudEvent to a specified sink. + params: + - name: sink + type: string + description: Sink to send Event to + - name: eventID + type: string + description: Event ID to use + - name: eventType + type: string + description: The Event Type to use + default: "tekton.cloudevent.message" + - name: source + type: string + description: Source of the CloudEvent + default: "" + - name: data + type: string + description: The payload of the Event + default: "" + steps: + - name: send + image: docker.io/iancoffey/sendevent-89c3de01c503ceb66b676a3e41c265ed@sha256:fc39998cba7ad8e54323b948b56b11b0b235996069349fb74776865fedf182a5 + command: ["sendevent"] + args: + - "--event-id=$(params.eventID)" + - "--event-type=$(params.eventType)" + - "--source=$(params.source)" + - "--data=$(params.data)" + - "$(params.sink)" diff --git a/task/cloudevent/0.2/config/task.yaml b/task/cloudevent/0.2/config/task.yaml new file mode 100644 index 0000000000..2b72c300fa --- /dev/null +++ b/task/cloudevent/0.2/config/task.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: cloudevent + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/tags: cloud +spec: + description: >- + This Task send a single CloudEvent to a specified sink. + params: + - name: sink + type: string + description: Sink to send Event to + - name: eventID + type: string + description: Event ID to use + - name: eventType + type: string + description: The Event Type to use + default: "tekton.cloudevent.message" + - name: source + type: string + description: Source of the CloudEvent + default: "" + - name: data + type: string + description: The payload of the Event + default: "" + steps: + - name: send + image: github.com/knative/eventing/cmd/sendevent + command: ["sendevent"] + args: + - "--event-id=$(params.eventID)" + - "--event-type=$(params.eventType)" + - "--source=$(params.source)" + - "--data=$(params.data)" + - "$(params.sink)" diff --git a/task/cloudevent/0.2/samples/event-display.yaml b/task/cloudevent/0.2/samples/event-display.yaml new file mode 100644 index 0000000000..efcec74a92 --- /dev/null +++ b/task/cloudevent/0.2/samples/event-display.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + name: eventdisplay +spec: + ports: + - port: 8080 + protocol: TCP + targetPort: 8080 + selector: + run: eventdisplay +--- +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: null + labels: + run: eventdisplay + name: eventdisplay +spec: + containers: + - image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display + name: eventdisplay + resources: {} + ports: + - containerPort: 8080 + protocol: TCP + dnsPolicy: ClusterFirst + restartPolicy: Never diff --git a/task/cloudevent/0.2/samples/run.yaml b/task/cloudevent/0.2/samples/run.yaml new file mode 100644 index 0000000000..8aa9b870a9 --- /dev/null +++ b/task/cloudevent/0.2/samples/run.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: cloudevent-send +spec: + params: + - name: sink + value: "http://eventdisplay.default.svc.cluster.local:8080" + - name: eventID + value: "ID-1234-5677" + - name: eventType + value: "test-event-type" + - name: source + value: "event-source-5000" + - name: data + value: "{\"data\": \"dude\"}" + taskRef: + name: cloudevent diff --git a/task/helm-conftest/0.2/README.md b/task/helm-conftest/0.2/README.md new file mode 100644 index 0000000000..0ce61cef9b --- /dev/null +++ b/task/helm-conftest/0.2/README.md @@ -0,0 +1,51 @@ +# Conftest + +These tasks make it possible to use [Conftest](https://github.com/instrumenta/conftest) within +your Tekton pipelines. Conftest is a tool for testing configuration files using [Open Policy Agent](https://openpolicyagent.org). + +## Installation + +Conftest also has a Helm plugin, which redners the Helm chart before applying the policy. For that task use: + +```console +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/helm-conftest/0.2/helm-conftest.yaml +``` + +## Helm usage + + +Once installed, the Helm task can be used as follows: + +```yaml +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: helm-conftest-example +spec: + taskRef: + name: helm-conftest + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source + params: + - name: chart + value: stable/mysql + - name: policy + value: stable/mysql/policy +``` + +## Parameters + +* **chart**: The chart to test against the specified policies (_default:_ `.`) +* **policy**: Where to find the policies (_default:_ `policy`) +* **output**: Which output format to use (_default:_ `stdout`) +* **args**: An array of additional arguments to pass to Conftest (_default `[]`) + +## Workspaces + +* **source**: A [Workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md) containing the source to build. + +## Platforms + +The Task can be run on `linux/amd64` platform. \ No newline at end of file diff --git a/task/helm-conftest/0.2/helm-conftest.yaml b/task/helm-conftest/0.2/helm-conftest.yaml new file mode 100644 index 0000000000..f6091df007 --- /dev/null +++ b/task/helm-conftest/0.2/helm-conftest.yaml @@ -0,0 +1,44 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: helm-conftest + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/categories: Testing + tekton.dev/tags: test + tekton.dev/displayName: "helm conftest" + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + These tasks make it possible to use Conftest within your Tekton pipelines + + Conftest is a tool for testing configuration files using Open Policy Agent. + + workspaces: + - name: source + params: + - name: chart + default: "." + - name: policy + default: "policy" + - name: output + default: "stdout" + - name: args + type: array + default: [] + + steps: + - name: helm-conftest + workingDir: $(workspaces.source.path) + image: docker.io/instrumenta/helm-conftest@sha256:11cb9fd6d101d80af87931db359d4b3ad9a843cf0eb1ea0ab7173424eb379948 + command: + - helm + - conftest + - $(params.chart) + - -p + - $(params.policy) + - -o + - $(params.output) + - $(params.args) diff --git a/task/prometheus-gate/0.2/README.md b/task/prometheus-gate/0.2/README.md new file mode 100644 index 0000000000..f11ebbe485 --- /dev/null +++ b/task/prometheus-gate/0.2/README.md @@ -0,0 +1,31 @@ +# Prometheus Gate + +A simple gate task which will query the prometheus API in a loop and await a matching status for N length of time. + +Code for the gate container is located at [github.com/iancoffey/prometheus-gate](https://github.com/iancoffey/prometheus-gate). + +## Strategy + +Currently, it is possible to enforce that a returned range query values all meet min, max and equals comparisons. Soon, p95 and p99 will be added as well. + +- *`min`* - enforce a minimum value for the time period +- *`max`* - enforce value does not exceed target during time period +- *`equals`* - enforce a target equals value for the entire time period + +## Range Query + +The gate can make use of any valid [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries). This approach works best when the dataset returned is tighly scoped via the range query itself. The gate considers an empty dataset as a failure to be retried. + +### Parameters + +* **prometheus_endpoint:**: Prometheus API endpoint +* **range_query:**: The range query to use to define SLO +* **range_time:**: The time we want to assert fits the SLO` +* **target_value:**: The target value to assert +* **target_strategy:**: min, max or equals. p95/99 not supported yet +* **timeout:**: Maximum ticker time for gate +* **tick_time:**: How often to try to assert the desired SLO + +## Platforms + +The Task can be run on `linux/amd64` platform. \ No newline at end of file diff --git a/task/prometheus-gate/0.2/prometheus-gate.yaml b/task/prometheus-gate/0.2/prometheus-gate.yaml new file mode 100644 index 0000000000..ead0ee466b --- /dev/null +++ b/task/prometheus-gate/0.2/prometheus-gate.yaml @@ -0,0 +1,62 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: prometheus-gate + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/categories: Monitoring + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/tags: gate, prometheus + tekton.dev/displayName: prometheus gate + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + A gate task which will query the prometheus API in a loop and await a matching status for N length of time. + + params: + - name: prometheus_endpoint + type: string + description: Prometheus API endpoint + - name: range_query + type: string + description: range query to use to define SLO + - name: range_time + type: string + description: time we want to assert fits the SLO + default: "-10m" + - name: target_value + type: string + description: value we will use as threshold + default: "1" + - name: target_strategy + type: string + description: The target_strategy is min,max or equal + default: "min" + - name: timeout + type: string + description: timeout of the gate + default: "3600" + - name: tick_time + type: string + description: how often to draw data from prometheus + default: "1m" + steps: + - name: gate + image: docker.io/iancoffey/prometheus-gate-cf7c3e662ede0a4e9bc24d37d2af86d6@sha256:c3df9d8400aef7acb76f409d1e347c5ecaa6f28a69df50981c14bfe87add85d7 + env: + - name: "PROMETHEUS_ENDPOINT" + value: $(params.prometheus_endpoint) + - name: "RANGE_QUERY" + value: $(params.range_query) + - name: "RANGE_TIME" + value: $(params.range_time) + - name: "TARGET_VALUE" + value: $(params.target_value) + - name: "TARGET_STRATEGY" + value: $(params.target_strategy) + - name: "TIMEOUT" + value: $(params.timeout) + - name: "TICK_TIME" + value: $(params.tick_time) diff --git a/task/prometheus-gate/0.2/samples/README.md b/task/prometheus-gate/0.2/samples/README.md new file mode 100644 index 0000000000..94e0ca9de4 --- /dev/null +++ b/task/prometheus-gate/0.2/samples/README.md @@ -0,0 +1,15 @@ +# Prometheus Gate Example + +When provided with a valid Prometheus API endpoint and an event sink, the sample Pipeline will await there being 0 *kube_endpoint_address_not_ready* metrics for 5 minutes before proceding to the second step, which sends a CloudEvent. + +## Params + +**prometheus_endpoint**: The API endpoint of your local (or remote) Prometheus API. The gate will use this endpoint to submit a range query every minute. + +**promotion_sink**: The URI to an event endpoint that can recieve events. + +## PipelineRun + +Edit the provided Pipeline run `gated-pipeline-run` to contain your prometheus API endpoint URI and an event sink promotion_sink. + +Once it is accurate, run the pipleine with `kubectl apply -f ./pipelinerun.yaml`. diff --git a/task/prometheus-gate/0.2/samples/pipeline.yaml b/task/prometheus-gate/0.2/samples/pipeline.yaml new file mode 100644 index 0000000000..a385dd8bee --- /dev/null +++ b/task/prometheus-gate/0.2/samples/pipeline.yaml @@ -0,0 +1,44 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: gated-pipeline +spec: + params: + - name: prometheus_endpoint + type: string + description: The triggers endpoint to send out completion CloudEvent + default: "" + - name: promotion_sink + type: string + description: The triggers endpoint to send out promotion CloudEvent + default: "" + tasks: + - name: gate-slo + taskRef: + name: prometheus-gate + params: + - name: range_time + value: "-5m" + - name: target_value + value: "0" + - name: prometheus_endpoint + value: "$(params.prometheus_endpoint)" + - name: range_query + value: kube_endpoint_address_not_ready{namespace="default"} + - name: target_strategy + value: equals + - name: send-promotion-events + taskRef: + name: cloudevent + params: + - name: sink + value: $(params.promotion_sink) + - name: eventID + value: "success.1234" + - name: eventType + value: "promoted.event" + - name: source + value: "development-pipeline" + - name: data + value: '{"message": "The gate succeeded. Woo"}' diff --git a/task/prometheus-gate/0.2/samples/pipelinerun.yaml b/task/prometheus-gate/0.2/samples/pipelinerun.yaml new file mode 100644 index 0000000000..2851c69d40 --- /dev/null +++ b/task/prometheus-gate/0.2/samples/pipelinerun.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: gated-pipeline-run +spec: + taskRunTemplate: + serviceAccountName: git-rebase-service-account + pipelineRef: + name: gated-pipeline + params: + - name: prometheus_endpoint + value: your.prometheus.endpoint:9090 + - name: promotion_sink + value: replace-with-your-uri diff --git a/task/pytest/0.3/README.md b/task/pytest/0.3/README.md new file mode 100644 index 0000000000..c05e80f212 --- /dev/null +++ b/task/pytest/0.3/README.md @@ -0,0 +1,59 @@ +# pytest + +The task provides test execution based on [pytest](https://pypi.org/project/pytest/) for Python. The used images are based on the official Docker Hub [Python images](https://hub.docker.com/_/python). The installation of the packages is performed via a `pip install`. + +**It is required that `pytest` is part of the requirements file for the task. If the module is not included a warning will be printed.** + +## Install the Task + +### Workspaces + +* **source**: A [Workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md) volume containing the python code. +* **pip-conf**: A [Workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md) volume containing the pip.conf to be used during testing. Is `optional`. + +### Install pytest + +```bash +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/pytest/0.3/pytest.yaml +``` + +## Parameters + +* **PYTHON_IMAGE**: The used Python image (_default_: `docker.io/python:3.11.1-bullseye`) +* **ARGS**: The additional arguments to be used with pytest +* **SOURCE_PATH**: The path to the source code (_default_: `.`) +* **REQUIREMENTS_FILE**: The name of the requirements file inside the source location, with fallback to the requirements file in the root location (_default_: `requirements.txt`) +* **PIP_CONF_FILE**: The name of the pip.conf file inside the pip conf workspace, with fallback to the normal name. (_default_: `pip.conf`) + +## Platforms + +The Task can be run on `linux/amd64`, `linux/s390x`, and `linux/ppc64le` platforms. + +## Usage + +This `TaskRun` runs `pytest` on a repository. + +```yaml +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: pytest +spec: + taskRef: + name: pytest + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source + # make sure your configmap contains + # a key "pip.conf" with the contents of your + # pip.conf + - name: pip-conf + configmap: + name: python-config + params: + - name: PYTHON_IMAGE + value: "docker.io/python:3.7" + - name: ARGS + value: "-rfs" +``` \ No newline at end of file diff --git a/task/pytest/0.3/pytest.yaml b/task/pytest/0.3/pytest.yaml new file mode 100644 index 0000000000..e5fec4dfe0 --- /dev/null +++ b/task/pytest/0.3/pytest.yaml @@ -0,0 +1,77 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: pytest + labels: + app.kubernetes.io/version: "0.3" + annotations: + tekton.dev/categories: Testing + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/tags: python, pytest + tekton.dev/displayName: pytest + tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le" +spec: + description: >- + This task will run pytest on the provided input. + + workspaces: + - name: source + - description: The workspace consisting of the custom pip settings. + name: pip-conf + optional: true + params: + - name: PYTHON_IMAGE + description: The used Python image + type: string + default: "docker.io/python:3.11.1-bullseye" + - name: ARGS + description: The additional arguments to be used with pytest + type: string + default: "" + - name: SOURCE_PATH + description: The path to the source code + default: "." + - name: REQUIREMENTS_FILE + description: The name of the requirements file inside the source location, with fallback to the requirements file in the root location + default: "requirements.txt" + - name: PIP_CONF_FILE + description: The name of the custom pip config file. + default: "pip.conf" + steps: + - name: unit-test + image: $(params.PYTHON_IMAGE) + workingDir: $(workspaces.source.path) + env: + - name: PARAM_PIP_CONF_FILE + value: $(params.PIP_CONF_FILE) + - name: WORKSPACE_PIP_CONF_BOUND + value: $(workspaces.pip-conf.bound) + - name: WORKSPACE_PIP_CONF_PATH + value: $(workspaces.pip-conf.path) + script: | + export PATH=$PATH:$HOME/.local/bin + + if [ "${WORKSPACE_PIP_CONF_BOUND}" = "true" ] ; then + export PIP_CONFIG_FILE="${WORKSPACE_PIP_CONF_PATH}/${PARAM_PIP_CONF_FILE}" + fi + + if [ -e "$(params.SOURCE_PATH)"/"$(params.REQUIREMENTS_FILE)" ]; + then + pip install -r "$(params.SOURCE_PATH)"/"$(params.REQUIREMENTS_FILE)" + pip show pytest || { + printf "###\nWarning: Pytest is missing in your test requirements file\n###"; + pip install pytest + } + else + if [ -e "$(params.REQUIREMENTS_FILE)" ]; + then + pip install -r "$(params.REQUIREMENTS_FILE)" + fi + pip install pytest + fi + if [ -z "$(params.ARGS)" ]; then + pytest "$(params.SOURCE_PATH)" + else + pytest "$(params.ARGS)" "$(params.SOURCE_PATH)" + fi diff --git a/task/pytest/0.3/tests/pre-apply-task-hook.sh b/task/pytest/0.3/tests/pre-apply-task-hook.sh new file mode 100644 index 0000000000..64f2208fb8 --- /dev/null +++ b/task/pytest/0.3/tests/pre-apply-task-hook.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Add git-clone +add_task git-clone latest diff --git a/task/pytest/0.3/tests/resources.yaml b/task/pytest/0.3/tests/resources.yaml new file mode 100644 index 0000000000..90a57e88ba --- /dev/null +++ b/task/pytest/0.3/tests/resources.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: python-source-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 200Mi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: python-config +data: + # possibility to add your own settings + custom-pip.conf: |- + [global] \ No newline at end of file diff --git a/task/pytest/0.3/tests/run.yaml b/task/pytest/0.3/tests/run.yaml new file mode 100644 index 0000000000..d2a5028636 --- /dev/null +++ b/task/pytest/0.3/tests/run.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: python-test-pipeline +spec: + workspaces: + - name: shared-workspace + - name: python-config + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/wumaxd/pylint-pytest-example.git + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + + - name: pytest + taskRef: + name: pytest + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: pip-conf + workspace: python-config + params: + - name: ARGS + value: "-rfs" + - name: PYTHON_IMAGE + value: "ghcr.io/tektoncd/python3.7@sha256:eedf63967cdb57d8214db38ce21f105003ed4e4d0358f02bedc057341bcf92a0" + - name: PIP_CONF_FILE + value: "custom-pip.conf" +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: python-test-pipeline-run +spec: + pipelineRef: + name: python-test-pipeline + workspaces: + - name: shared-workspace + persistentVolumeClaim: + claimName: python-source-pvc + - name: python-config + configMap: + name: python-config diff --git a/task/robot-framework/0.2/README.md b/task/robot-framework/0.2/README.md new file mode 100644 index 0000000000..ce1c95fa12 --- /dev/null +++ b/task/robot-framework/0.2/README.md @@ -0,0 +1,74 @@ +# Robot Framework + +This task runs [Robot Framework](https://robotframework.org/) tests that are provided in the source workspace. Additional configuration is possible with a [variable file](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#resource-and-variable-files). + +## Install the Task + +```bash +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/robot-framework/0.2/robot-framework.yaml +``` + +## Workspaces + +- source: A workspace containing Robot Framework tests. Results are written to `/reports`. + +- variables-file: An optional workspace to add a variable file. Useful if you have want to use a secret for credentials, url's, etc. + +## Parameters + +- **IMAGE**: Optional: Default uses a basic python image and installs test requirements during runtime. It's also possible to use your own image which has requirements pre-installed. +- **REQUIREMENTS_FILE**: Optional: Requirements file to use for installing test requirements +- **ROBOT_OPTIONS**: Optional: Arguments to use with the robot command +- **TEST_DIR**: Directory that contains robot tests +- **VARIABLES_FILE**: Optional: Name of the variable file provided in the workspace. A .py extension is necessary. + +## Platforms + +The Task can be run on `linux/amd64` platform. + +## Usage + +Basic usage without installing extra requirements or using a variables file: + +```yaml +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: example-run +spec: + taskRef: + name: robot-framework + params: + - name: TEST_DIR + value: ./rf-tests + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source +``` + +Using a secret that contains a variable file (called `variables.py`): + +```yaml +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: example-run +spec: + taskRef: + name: robot-framework + params: + - name: TEST_DIR + value: ./rf-tests + - name: VARIABLES_FILE + value: variables.py + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source + - name: variables-file + secret: + secretName: variables +``` + +Result files are written to `/reports` in the source workspace. If you want to store the files long-term make sure to upload them to S3 or something similar. \ No newline at end of file diff --git a/task/robot-framework/0.2/robot-framework.yaml b/task/robot-framework/0.2/robot-framework.yaml new file mode 100644 index 0000000000..69c604605b --- /dev/null +++ b/task/robot-framework/0.2/robot-framework.yaml @@ -0,0 +1,80 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: robot-framework + labels: + app.kubernetes.io/version: "0.2" + annotations: + tekton.dev/categories: Testing + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/tags: python, robot-framework + tekton.dev/displayName: robot-framework + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + This task will run Robot Framework tests in the source workspace. + + workspaces: + - name: source + description: A workspace containing .robot test files + - name: variables-file + optional: true + description: A Workspace containing a Robot Framework variables file (usually a secret) + params: + - name: IMAGE + description: The image used to run the tests. This can be a base python image, or an image that already has pre-requirements installed. + type: string + default: "python@sha256:4ec7de21666118edfa1b90c79b34c282624d03e2e560fa1b542b2069a65b367f" + - name: REQUIREMENTS_FILE + description: Optional requirements file to use for installing test requirements + type: string + default: "" + - name: ROBOT_OPTIONS + description: Arguments to use with the robot command + type: string + default: "" + - name: TEST_DIR + description: Directory that contains robot tests + type: string + - name: VARIABLES_FILE + description: Name of the variable file provided in the workspace. A .py extension is necessary. + type: string + default: "variables.py" + steps: + - name: robot-tests + image: $(params.IMAGE) + workingDir: $(workspaces.source.path) + script: | + export PATH=$PATH:$HOME/.local/bin + + if [ -n "$(inputs.params.REQUIREMENTS_FILE)" ]; + then + if [ -e "$(workspaces.source.path)"/"$(inputs.params.REQUIREMENTS_FILE)" ]; + then + pip install -r "$(workspaces.source.path)"/"$(inputs.params.REQUIREMENTS_FILE)" + pip show robotframework || { + printf "###\nWarning: Robot Framework is missing in your test requirements file\n###"; + pip install robotframework + } + else + printf "###\nError: Parameter for requirements file was provided, but file was not found in source workspace. Exiting.\n###"; + exit 1 + fi + else + printf "###\nInfo: No parameter for requirements file was provided, only Robot Framework will be installed.\n###"; + pip install robotframework + fi + + if [ -n '$(workspaces.variables-file.path)' ]; + then + if [ -e "$(workspaces.variables-file.path)"/"$(inputs.params.VARIABLES_FILE)" ]; + then + robot --outputdir ./reports -V $(workspaces.variables-file.path)/$(params.VARIABLES_FILE) $(params.ROBOT_OPTIONS) $(params.TEST_DIR) + else + printf "\nERROR: Variables file $(params.VARIABLES_FILE) not found in workspace. Exiting." + exit 1 + fi + else + robot --outputdir ./reports $(params.ROBOT_OPTIONS) $(params.TEST_DIR) + fi diff --git a/task/robot-framework/0.2/tests/pre-apply-task-hook.sh b/task/robot-framework/0.2/tests/pre-apply-task-hook.sh new file mode 100755 index 0000000000..8226665e86 --- /dev/null +++ b/task/robot-framework/0.2/tests/pre-apply-task-hook.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Add write-file +add_task write-file latest diff --git a/task/robot-framework/0.2/tests/run.yaml b/task/robot-framework/0.2/tests/run.yaml new file mode 100644 index 0000000000..d941647902 --- /dev/null +++ b/task/robot-framework/0.2/tests/run.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + generateName: robot-framework-test- +spec: + workspaces: + - name: shared-workspace + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi + pipelineSpec: + workspaces: + - name: shared-workspace + tasks: + - name: write-file + taskRef: + name: write-file + params: + - name: path + value: ./robot/test.robot + - name: contents + value: | + *** Test Cases *** + Testcase 1 + Log To Console 'Testcase 1' + workspaces: + - name: output + workspace: shared-workspace + - name: robot-framework + runAfter: [write-file] + taskRef: + name: robot-framework + params: + - name: TEST_DIR + value: "./" + workspaces: + - name: source + workspace: shared-workspace diff --git a/task/upload-pypi/0.3/README.md b/task/upload-pypi/0.3/README.md new file mode 100644 index 0000000000..779e687c30 --- /dev/null +++ b/task/upload-pypi/0.3/README.md @@ -0,0 +1,91 @@ +# Publish-Python-Package + +This Task publishes Python packages to PyPI index using [Twine](https://pypi.org/project/twine/) utility module. It provides build system independent uploads of source and binary distribution artifacts for both new and existing projects. + +## Changelog + +- Added optional parameters for secret name and keys +- Added optional prebuild script parameter +- Added builder image parameter and changed to python image instead of Twine + +## Install the Task + +``` +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/v1beta1/task/upload-pypi/0.3/upload-pypi.yaml +``` +## Requirement + +A secret is needed with Twine credentials for python module publishing to PyPI index. The default name is `pypi-secret`, and default keys are: + +- **username**: The username to authenticate to the repository (package index). +- **password**: The password to authenticate to the repository (package index). + +These values can be overwritten using the parameters. + +``` +apiVersion: v1 +kind: Secret +metadata: + name: pypi-secret +type: kubernetes.io/basic-auth +stringData: + username: foo + password: bar +``` + +## Parameters + +* **TWINE_REPOSITORY_URL**: The repository (package index) to upload the package to. +* **SECRET_NAME**: Name of the secret containing the username & password used to upload the package. +* **SECRET_USERNAME_KEY**: Name of the secret key containing the username. +* **SECRET_PASSWORD_KEY**: Name of the secret key containing the password. +* **PREBUILD_SCRIPT**: Script to run prior to build. Useful for installing dependencies. +* **BUILDER_IMAGE**: Image to use for building the package. + +## Workspaces + +* **source**: A [Workspace](https://github.com/tektoncd/pipeline/blob/main/docs/workspaces.md) containing the source to build. + +## Platforms + +The Task can be run on `linux/amd64` platform. + +## Usage + +This TaskRun runs the Task to fetch a Git repo, and build and publishes a python module. + +``` +apiVersion: tekton.dev/v1 +kind: TaskRun +metadata: + name: publish-package +spec: + taskRef: + name: upload-pypi + workspaces: + - name: source + persistentVolumeClaim: + claimName: my-source +``` + +In this example, the Git repo being used is expected to have a `setup.py` file at the root of the repository. [setup.py](https://packaging.python.org/tutorials/packaging-projects/#creating-setup-py) is build script for [setuptools](https://pypi.org/project/setuptools/) + +This TaskRun outputs several `Results`: + +- A `sha256` hash for each uploaded file (the bdist and the sdist packages). +- The name of the uploaded package +- The version of the uploaded package + +This looks like: + +``` + taskResults: + - name: bdist_sha + value: 97dd35b7097443b6896734d979a1a52c64023f17474e4027d69d2df0b9acb797 dist/foo.whl + - name: package_name + value: foo + - name: package_version + value: 2.24.4 + - name: sdist_sha + value: 8fda69bc68ece690d135d0091ebdd10a8c15db477c2eafce0d0a65bc9712f5bf dist/foo.tar.gz +``` diff --git a/task/upload-pypi/0.3/samples/run.yaml b/task/upload-pypi/0.3/samples/run.yaml new file mode 100644 index 0000000000..10fcdc3e37 --- /dev/null +++ b/task/upload-pypi/0.3/samples/run.yaml @@ -0,0 +1,66 @@ +apiVersion: v1 +kind: Secret +metadata: + name: pypi-secret +type: kubernetes.io/basic-auth +stringData: + username: foo + password: bar +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: shared-task-storage +spec: + resources: + requests: + storage: 500Mi + accessModes: + - ReadWriteOnce +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: publish-package-pipeline +spec: + workspaces: + - name: shared-workspace + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: https://github.com/pypa/twine.git + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + + - name: upload-pypi-run + taskRef: + name: upload-pypi + workspaces: + - name: source + workspace: shared-workspace + runAfter: + - fetch-repository +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: publish-package-pipeline-run +spec: + podTemplate: + securityContext: + runAsNonRoot: false + runAsUser: 0 + pipelineRef: + name: publish-package-pipeline + workspaces: + - name: shared-workspace + persistentVolumeClaim: + claimName: shared-task-storage diff --git a/task/upload-pypi/0.3/tests/pre-apply-task-hook.sh b/task/upload-pypi/0.3/tests/pre-apply-task-hook.sh new file mode 100644 index 0000000000..e38f9e3eeb --- /dev/null +++ b/task/upload-pypi/0.3/tests/pre-apply-task-hook.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Add pypiserver sidecar +add_sidecars ${TMPF} '{"image":"pypiserver/pypiserver:v1.4.2", "name": "pypiserver", "args": ["-P .", "-a ."]}' + +# Add git-clone +add_task git-clone latest diff --git a/task/upload-pypi/0.3/tests/resources.yaml b/task/upload-pypi/0.3/tests/resources.yaml new file mode 100644 index 0000000000..64ceb30e9d --- /dev/null +++ b/task/upload-pypi/0.3/tests/resources.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: upload-pypi-source-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 500Mi +--- +apiVersion: v1 +kind: Secret +metadata: + name: pypi-secret +type: kubernetes.io/basic-auth +stringData: + username: foo + password: bar diff --git a/task/upload-pypi/0.3/tests/run.yaml b/task/upload-pypi/0.3/tests/run.yaml new file mode 100644 index 0000000000..526d02a817 --- /dev/null +++ b/task/upload-pypi/0.3/tests/run.yaml @@ -0,0 +1,47 @@ +--- +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: upload-pypi-test-pipeline +spec: + workspaces: + - name: shared-workspace + tasks: + - name: fetch-repository + taskRef: + name: git-clone + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: 'https://github.com/pypa/sampleproject' + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: revision + value: d4ee05fdc03e848ed6e7065d8fe8e833a3c8c0b2 + - name: upload-pypi-run + params: + - name: TWINE_REPOSITORY_URL + value: 'http://localhost:8080/' + taskRef: + name: upload-pypi + workspaces: + - name: source + workspace: shared-workspace + runAfter: + - fetch-repository +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: upload-pypi-test-pipeline-run +spec: + pipelineRef: + name: upload-pypi-test-pipeline + workspaces: + - name: shared-workspace + persistentVolumeClaim: + claimName: upload-pypi-source-pvc diff --git a/task/upload-pypi/0.3/upload-pypi.yaml b/task/upload-pypi/0.3/upload-pypi.yaml new file mode 100644 index 0000000000..4c33011ac5 --- /dev/null +++ b/task/upload-pypi/0.3/upload-pypi.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: upload-pypi + labels: + app.kubernetes.io/version: "0.3" + annotations: + tekton.dev/pipelines.minVersion: "0.50.0" + tekton.dev/categories: Publishing + tekton.dev/tags: build + tekton.dev/displayName: "upload pypi" + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + This Task publishes Python packages to PyPI index using Twine utility module. + + It provides build system independent uploads of source and binary distribution + artifacts for both new and existing projects. + + params: + - name: TWINE_REPOSITORY_URL + description: The repository (package index) to upload the package to. + default: "https://upload.pypi.org/legacy/" + type: string + - name: SECRET_NAME + description: Name of the secret containing the username & password used to upload the package. + default: "pypi-secret" + type: string + - name: SECRET_USERNAME_KEY + description: Name of the secret key containing the username. + default: "username" + type: string + - name: SECRET_PASSWORD_KEY + description: Name of the secret key containing the password. + default: "password" + type: string + - name: PREBUILD_SCRIPT + description: Script to execute prior to running setup.py. + type: string + default: '' + - name: BUILDER_IMAGE + description: Image to use for building the package + type: string + default: 'python:3.9' + + workspaces: + - name: source + + steps: + - name: build-package + image: $(params.BUILDER_IMAGE) + workingDir: $(workspaces.source.path) + script: | + $(params.PREBUILD_SCRIPT) + + python setup.py sdist bdist_wheel + - name: upload-package + image: quay.io/thoth-station/twine:v0.0.2@sha256:1d7eabedfb2fb72b816e5a06e995966fa74c42a0df38ac0065a02caa48b7dc97 #tag: v0.0.2 + workingDir: $(workspaces.source.path) + env: + - name: TWINE_REPOSITORY_URL + value: $(params.TWINE_REPOSITORY_URL) + - name: TWINE_USERNAME + valueFrom: + secretKeyRef: + name: $(params.SECRET_NAME) + key: $(params.SECRET_USERNAME_KEY) + - name: TWINE_PASSWORD + valueFrom: + secretKeyRef: + name: $(params.SECRET_NAME) + key: $(params.SECRET_PASSWORD_KEY) + script: | + twine upload --disable-progress-bar dist/* + # Now write out all our results, stripping newlines. + # sdist files are .tar.gz's + sha256sum dist/*.tar.gz | tr -d '\n' | tee $(results.sdist_sha.path) + # bdist files are .whls's + sha256sum dist/*.whl | tr -d '\n' | tee $(results.bdist_sha.path) + python setup.py --name | tr -d '\n' | tee $(results.package_name.path) + python setup.py --version | tr -d '\n' | tee $(results.package_version.path) + results: + - name: sdist_sha + description: sha256 (and filename) of the sdist package + - name: bdist_sha + description: sha256 (and filename) of the bdist package + - name: package_name + description: name of the uploaded package + - name: package_version + description: version of the uploaded package