/github-actions-typing

Bring type-safety to your GitHub actions' API!

Primary LanguageKotlinApache License 2.0Apache-2.0

GitHub Actions typing

Bring type-safety to your GitHub actions' API!

This is a GitHub action that validates your action's type specs (action-types.y(a)ml) and ensures the inputs and outputs have types set according to a certain specification. It aims to be a standardized way to present your actions' API, both to human users and any kind of automation (e. g. generating action bindings for this Kotlin DSL). Similar to typings for TypeScript or type hints for Python.

It supports YAML anchors and aliases to reduce duplication.

To see which actions already provide typings using this schema, click here.

Example

Let's say your action has such manifest (action.yml):

name: My cool action
description: Just to showcase GitHub Actions typing
inputs:
  verbose:
    description: 'Set to true to display debug information helpful when troubleshooting issues with this action.'
    required: false
    default: 'false'
  log-level:
    description: 'Specify the level of details for logging.'
    required: true
  permissions:
    description: 'Who should have access.'
runs:
  using: 'node16'
  image: 'dist/main.js'

and such action-types.yml next to it:

inputs:
  verbose:
    type: boolean
  permissions:
    type: inttteger

This action, once used within a workflow, will fail the workflow run and produce such output:

Example output

Usage

Create a new file in your action repo's root directory: action-types.yml, then specify types for your action's inputs and outputs. See "Available types" section below.

Finally, create a workflow in your actions' repository that will simply call this action to validate the types:

name: Validate action typings

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

jobs:
  validate-typings:
    runs-on: "ubuntu-latest"
    steps:
      - uses: actions/checkout@v3
      - uses: typesafegithub/github-actions-typing@v1

Available types

String

A text value.

Example:

...
inputs:
  name:
    type: string
    ...

Boolean

Can be true or false.

Example:

...
inputs:
  verbose:
    type: boolean
    ...

Integer

A number without a fractional component.

Example:

...
inputs:
  retries:
    type: integer
    ...

In case of "magic values" meaning something else that the user would expect, you can specify them like so:

...
inputs:
  fetch-depth:
    type: integer
    named-values:
      infinite: 0
    ...

You can also optionally define name which is a hint for code generators what name can be used as class name.

...
inputs:
  fetch-depth:
    type: integer
    name: Amount
    named-values:
      infinite: 0
    ...

Float

A number with a fractional component.

Example:

...
inputs:
  threshold:
    type: float
    ...

List

A sequence of values.

Because string is used as a data type for passing inputs to actions, a separator string has to be specified as well. This is usually a new line or a comma.

Lists can contain values of any primitive or enum type.

If your list items are in separate line each, use "\n" as separator.

Examples:

...
inputs:
  input-files:
    type: list
    separator: ','
    list-item:
      type: string
  ...
...
inputs:
  granted-scopes:
    type: list
    separator: ','
    list-item:
      type: enum
      allowed-values:
        - read
        - write
  ...

Enum

Multiple possible values.

You can also optionally define name which is a hint for code generators what name can be used as enum type name.

Example:

...
inputs:
  permissions:
    type: enum
    allowed-values:
      - user
      - admin
      - guest
  if_mention:
    type: enum
    name: MentionStatus
    allowed-values:
      - success
      - failure
    ...