Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(outputs): add docs for outputs #426

Merged
merged 2 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions content/usage/outputs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: "Outputs"
toc: true
description: >
Learn how to configure outputs for steps.
---

{{% alert title="Tip:" color="info" %}}
Outputs functionality is only available in the Docker runtime.
{{% /alert %}}

### What are outputs and why are they useful?

While the workspace [is shared](/docs/usage/workspace) for all steps in a build, the environment is not. This is because changes to a container environment are not exported after the completion of a step.

For example, take the following pipeline:

```yaml
version: "1"

steps:
- name: parse image for testing
image: alpine:latest
commands:
# image to use is the first part of the source branch (inventory-updates -> my-organization/inventory:latest)
- image=$(echo ${VELA_PULL_REQUEST_SOURCE} | sed 's/[_.-].*//')

- name: test
image: my-organization/${image}:latest
pull: on_start
commands:
- go test ./...

```

This is not a valid pipeline configuration because `image` will not persist from the first step to the second. However, being able to dynamically update environment variables for substitution or for plugin parameters can be an important part of a CI build.

This is where `outputs` can improve your pipeline configurations.

Let's take the same pipeline but make it valid using outputs:

```yaml
version: "1"

steps:
- name: parse image for testing
image: alpine:latest
commands:
# image to use is the first part of the source branch (inventory-updates -> my-organization/inventory:latest)
- echo "image=$(echo ${VELA_PULL_REQUEST_SOURCE} | sed 's/[_.-].*//')" > $VELA_OUTPUTS

- name: test
image: my-organization/${image}:latest
pull: on_start
commands:
- go test ./...
```

Writing to `$VELA_OUTPUTS` in environment file format ensures that those key-value pairs persist for the entirety of the build.

Not only is this more convenient than storing information in the shared workspace, it can also be safer. Vela secrets are masked in logs, but any sensitive value captured during a build has the potential to be leaked in logs if steps or plugins are not configured correctly.

This can be remedied with masked outputs:

```yaml
version: "1"

steps:
- name: capture API key for testing
image: alpine:latest
commands:
- apk add jq
- echo "API_KEY=$(curl http://my-test-endpoint/token | jq .token)" > $VELA_MASKED_OUTPUTS

- name: test
image: golang:latest
commands:
- echo $API_KEY # will print ***
- go test ./...
```

After the first step is complete, the logs will mask any mention of the `$API_KEY`.

### Limitations

- Outputs can only be used as environment variables (`$VAR`) or substitution variables (`${VAR}`). Inline Go templating (`{{ .VAR }}`) is done at compile time and will not dynamically be evaluated.

- Masking will only be applied to variables in `$VELA_MASKED_OUTPUTS` in steps that run _after_ the variable has been written. In other words, if `Step A` writes a token to `$VELA_MASKED_OUTPUTS`, `Step A` logs will _not_ mask the value. Only subsequent steps will have the masking applied.
2 changes: 1 addition & 1 deletion themes/docsy/layouts/partials/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{{- template "_internal/schema.html" . -}}
{{- template "_internal/twitter_cards.html" . -}}
{{ if eq (getenv "HUGO_ENV") "production" }}
{{ template "_internal/google_analytics_async.html" . }}
{{ template "_internal/google_analytics.html" . }}
{{ end }}
{{ partialCached "head-css.html" . "asdf" }}
<script
Expand Down
Loading