doc: templates #829
This commit is contained in:
parent
03a9a05e38
commit
a3413c0bc3
|
|
@ -79,6 +79,7 @@
|
|||
** xref:args/input_textarea.adoc[Input: Textarea]
|
||||
** xref:args/suggestions.adoc[Suggestions]
|
||||
** xref:args/env.adoc[Environment Variables]
|
||||
** xref:args/templates.adoc[Templates]
|
||||
* xref:dashboards/intro.adoc[Dashboards]
|
||||
** xref:dashboards/examples.adoc[Examples]
|
||||
** xref:dashboards/actions.adoc[Actions (Linked)]
|
||||
|
|
|
|||
|
|
@ -49,6 +49,6 @@ actions:
|
|||
shellAfterCompleted: "apprise -t 'Backup on {{ .Env.HOSTNAME }}' -b '{{ output }}'"
|
||||
----
|
||||
|
||||
`.Env` uses the same Go template context as other action variables (e.g. `.Arguments`, `.CurrentEntity`, `.OliveTin`). The map is built from the process environment when OliveTin starts; values are read at template execution time. If a variable is missing, the template engine will report a missing-key error (with `missingkey=error`), so use defaulting when a variable might be unset, e.g. `{{ or .Env.OPTIONAL_VAR "default" }}`.
|
||||
`.Env` uses the same Go template context as other action variables (e.g. `.Arguments`, `.CurrentEntity`, `.OliveTin`). The map is built from the process environment when OliveTin starts; values are read at template execution time. If a variable is missing, the template engine will report a missing-key error (with `missingkey=error`), so use defaulting when a variable might be unset, e.g. `{{ or .Env.OPTIONAL_VAR "default" }}`. For template functions such as JSON encoding, see xref:args/templates.adoc#json-encoding[JSON encoding with Json].
|
||||
|
||||
This feature addresses the need to use environment variables in templates without changing the config loader (see link:https://github.com/OliveTin/OliveTin/issues/840[GitHub issue #840]).
|
||||
|
|
|
|||
|
|
@ -85,11 +85,11 @@ fi
|
|||
|
||||
To use the *process* environment (the environment OliveTin was started with) inside action template fields such as `shell` or `shellAfterCompleted`, use the `.Env` template variable: `{{ .Env.VAR_NAME }}`. This substitutes the value at execution time. See xref:advanced_configuration/config_envs.adoc#using-env-in-template-replacements[Using .Env in template replacements] for details and examples.
|
||||
|
||||
For other template features, including JSON encoding of argument and entity values, see xref:args/templates.adoc[Templates in actions].
|
||||
|
||||
== Notes
|
||||
|
||||
. Argument names are converted to uppercase for environment variables, `name: filename` becomes `FILENAME`.
|
||||
. OliveTin sets `OLIVETIN=1` in the process environment for every action; see <<olivetin-env-var,The OLIVETIN environment variable>> above.
|
||||
. The execution request variables are exposed as `OT_USERNAME` and `OT_EXECUTIONTRACKINGID` in the process environment; see <<execution-request-variables,Execution Request Variables>> above.
|
||||
. The environment variables are passed into the execution context which uses a shell (/bin/sh on Linux), so it is also possible to use them with the $ notation in the `shell` line, like this; `shell: echo $FILENAME` for example.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,5 @@ Now that you understand how arguments work, explore the different argument types
|
|||
* xref:args/suggestions.adoc[Argument suggestions] - Add dynamic suggestions to help users
|
||||
* xref:args/regex.adoc[Input validation with regex] - Validate user input with regular expressions
|
||||
* xref:args/env.adoc[Environment variables] - Use arguments to set environment variables
|
||||
* xref:args/templates.adoc[Templates] - Use Go templates in actions, including JSON encoding
|
||||
* xref:action_examples/intro.adoc[See examples] - View real-world examples using arguments
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
[#templates]
|
||||
= Templates in actions
|
||||
|
||||
OliveTin uses https://pkg.go.dev/text/template[Go text/template] syntax in action fields such as `shell`, `shellAfterCompleted`, entity directory titles, and `enabledExpression`. Template placeholders are written as `{{ ... }}`.
|
||||
|
||||
In OliveTin 3k, use dotted names for template context variables:
|
||||
|
||||
* `{{ .Arguments.NAME }}` — argument values (see xref:args/env.adoc[Environment variables])
|
||||
* `{{ .CurrentEntity.property }}` — entity properties (see xref:entities/intro.adoc[Entities])
|
||||
* `{{ .Env.VAR_NAME }}` — process environment (see xref:advanced_configuration/config_envs.adoc#using-env-in-template-replacements[Using .Env in template replacements])
|
||||
* `{{ .OliveTin.Build.Version }}` and related build/runtime fields
|
||||
|
||||
In OliveTin 2k, argument and execution-request placeholders used the shorter form (for example, `{{ message }}` instead of `{{ .Arguments.message }}`).
|
||||
|
||||
[#json-encoding]
|
||||
== JSON encoding with `Json`
|
||||
|
||||
The `Json` template function encodes a value as a JSON string. Pipe a template value to it when you need structured data in a command — for example, passing argument or entity state to a script or HTTP client that expects JSON.
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
actions:
|
||||
- title: curl my knx thing
|
||||
shell: curl --json https://knx.example.com/v1/group/global_on/write -d '{{ .Arguments | Json }}'
|
||||
entity: light
|
||||
arguments:
|
||||
- name: value
|
||||
default: "true"
|
||||
----
|
||||
|
||||
After template substitution, `{{ .Arguments | Json }}` becomes a JSON object containing all argument names and values for that execution (including execution-request variables such as `ot_username` and `ot_executionTrackingId`).
|
||||
|
||||
=== Examples
|
||||
|
||||
Encode a single argument value:
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
shell: echo {{ .Arguments.value | Json }}
|
||||
----
|
||||
|
||||
If `value` is `hello`, the substituted command is `echo "hello"`.
|
||||
|
||||
Encode an entity field:
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
shell: curl -d {{ .CurrentEntity.foo.bar | Json }}
|
||||
----
|
||||
|
||||
If `foo.bar` is the string `baz`, the substituted command is `curl -d "baz"`.
|
||||
|
||||
Encode a nested entity object:
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
shell: curl --json -d {{ .CurrentEntity.payload | Json }}
|
||||
----
|
||||
|
||||
If `payload` is `{on: true}`, the substituted command is `curl --json -d {"on":true}`.
|
||||
|
||||
=== Notes
|
||||
|
||||
. `Json` uses Go's `encoding/json` package. Strings, numbers, booleans, objects, and arrays are encoded according to normal JSON rules.
|
||||
. Argument values in templates are strings (`map[string]string`). A checkbox or boolean argument therefore appears in JSON as a string (for example, `"true"`), not a JSON boolean.
|
||||
. If the piped value is missing or nil, `Json` produces `null`.
|
||||
. When embedding JSON in a shell command, quote the substitution if the JSON may contain spaces or shell metacharacters. Prefer single-quoted YAML strings around the template when possible, as shown in the curl example above.
|
||||
. For HTTP request bodies, pass one JSON-encoded value (or build the JSON structure you need in one template expression). Piping several values with spaces between them does not produce a single valid JSON document.
|
||||
|
||||
See link:https://github.com/OliveTin/OliveTin/issues/829[GitHub issue #829] for the original feature request.
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# macOS release signing
|
||||
|
||||
Release builds can sign and notarize the `darwin` binaries using [quill](https://github.com/anchore/quill) via GoReleaser. This runs on the existing Linux CI runner; no macOS runner is required.
|
||||
|
||||
Signing is **optional**. If the GitHub secrets below are not all set, GoReleaser skips macOS signing and publishes unsigned binaries (the previous behaviour).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- An active [Apple Developer Program](https://developer.apple.com/programs/) membership.
|
||||
- A **Developer ID Application** certificate (not "Apple Development" or "Mac App Distribution").
|
||||
- An [App Store Connect API key](https://appstoreconnect.apple.com/access/integrations/api) with at least **Developer** access.
|
||||
|
||||
## One-time setup
|
||||
|
||||
### 1. Create the signing certificate
|
||||
|
||||
1. Open [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/certificates/list).
|
||||
2. Create a certificate of type **Developer ID Application**.
|
||||
3. Download the `.cer` file and double-click it to add it to **Keychain Access** on a Mac.
|
||||
4. In Keychain Access, export the certificate as a **Personal Information Exchange (`.p12`)** file. You will set an export password — remember it; this becomes `MACOS_SIGN_PASSWORD`.
|
||||
|
||||
### 2. Create the notarization API key
|
||||
|
||||
1. Open [App Store Connect → Users and Access → Integrations → App Store Connect API](https://appstoreconnect.apple.com/access/integrations/api).
|
||||
2. Create a key with **Developer** role (or Admin).
|
||||
3. Download the `.p8` file once (it cannot be downloaded again). Note the **Key ID** shown in the portal and the **Issuer ID** at the top of the API keys page.
|
||||
|
||||
### 3. Base64-encode the key files
|
||||
|
||||
Run on a machine that has the files (Linux or macOS):
|
||||
|
||||
```sh
|
||||
base64 -w0 < ./Certificates.p12 # MACOS_SIGN_P12
|
||||
base64 -w0 < ./AuthKey_XXXXXX.p8 # MACOS_NOTARY_KEY
|
||||
```
|
||||
|
||||
On macOS without GNU coreutils, use `base64 -i file | tr -d '\n'`.
|
||||
|
||||
### 4. Add GitHub repository secrets
|
||||
|
||||
In **Settings → Secrets and variables → Actions**, create:
|
||||
|
||||
| Secret | Value |
|
||||
|--------|-------|
|
||||
| `MACOS_SIGN_P12` | Base64 contents of the `.p12` file |
|
||||
| `MACOS_SIGN_PASSWORD` | Password used when exporting the `.p12` |
|
||||
| `MACOS_NOTARY_KEY` | Base64 contents of the `.p8` file |
|
||||
| `MACOS_NOTARY_KEY_ID` | Key ID from App Store Connect (e.g. `ABC123DEF4`) |
|
||||
| `MACOS_NOTARY_ISSUER_ID` | Issuer UUID from App Store Connect |
|
||||
|
||||
All five must be present for signing to run. Any missing secret disables signing for that release.
|
||||
|
||||
## Renewal
|
||||
|
||||
| Item | Typical lifetime | What to do |
|
||||
|------|------------------|------------|
|
||||
| Developer ID Application certificate | ~5 years | Create a new certificate in the Apple portal, export a new `.p12`, update `MACOS_SIGN_P12` and `MACOS_SIGN_PASSWORD`. |
|
||||
| App Store Connect API key | Does not expire, but can be revoked | Create a new key if compromised or lost; update `MACOS_NOTARY_KEY`, `MACOS_NOTARY_KEY_ID`, and optionally `MACOS_NOTARY_ISSUER_ID`. |
|
||||
| Apple Developer Program | Annual subscription | Renew membership before it lapses; existing certificates stop working if the account is inactive. |
|
||||
|
||||
After updating secrets, the next release on `main` (via semantic-release) will use the new credentials automatically.
|
||||
|
||||
## Verifying a signed release
|
||||
|
||||
On a Mac, download a `OliveTin-darwin-*.tar.gz` release artifact and run:
|
||||
|
||||
```sh
|
||||
tar -xzf OliveTin-darwin-arm64.tar.gz
|
||||
spctl -a -vv -t execute OliveTin-darwin-arm64/OliveTin
|
||||
```
|
||||
|
||||
A signed and notarized binary should report `accepted` with `source=Notarized Developer ID`.
|
||||
|
||||
## Configuration reference
|
||||
|
||||
- GoReleaser: `notarize.macos` in [`.goreleaser.yml`](.goreleaser.yml)
|
||||
- CI secrets: [`.github/workflows/build-and-release.yml`](.github/workflows/build-and-release.yml) (`release` step)
|
||||
- [GoReleaser notarization docs](https://goreleaser.com/customization/notarize/)
|
||||
Loading…
Reference in New Issue