Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

151 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shared-actions

Contains all of the shared composite actions used by RAPIDS. Several of these actions, especially the telemetry actions, use a pattern that we refer to as "dispatch actions." The general idea of a dispatch action is to make it easier to depend on other actions at a specific revision, and also to simplify using files beyond a given action .yml file.

A dispatch action is one that:

  • clones the shared-actions repository (repo/ref changeable using env vars)
  • runs (dispatches to) another action within the clone, using a relative path

Release build-output companions

release-build-output-dispatch validates a producer's local build artifact directory and uploads a companion artifact named release-build-output-<source-artifact-name>. The companion contains release-build-output.json, release-build-metadata.json, provenance, and an SBOM record for every primary artifact.

Conda and wheel jobs can set artifact-type to conda or wheel and omit release-artifacts; the implementation reads package metadata from the built files. Custom bundles provide explicit artifact descriptors and either inline package identity or a producer-created package JSON file.

- name: Create release build-output companion
  uses: rapidsai/shared-actions/release-build-output-dispatch@main
  with:
    artifact-type: wheel
    output-directory: ${{ steps.package-name.outputs.WHEEL_OUTPUT_DIR }}
    release-unit: wheel:example
    source-artifact-name: ${{ steps.package-name.outputs.RAPIDS_PACKAGE_NAME }}
    source-sha: ${{ github.sha }}

A descriptor-selected producer SBOM is classified as producer-dependency. When no SBOM is supplied, the action generates an SPDX artifact-identity envelope and classifies it as generated-identity. The generated envelope contains the primary artifact's identity and SHA-256 but no dependency inventory; it must not be treated as dependency coverage.

The dispatch wrapper honors SHARED_ACTIONS_REPO and SHARED_ACTIONS_REF. When neither is set, it checks out the same repository and ref used to invoke the wrapper, which allows a feature-branch wrapper to dispatch to its matching implementation during canary testing.

There can be more complicated arrangements of more actions, but the idea is to have the local clone of the shared-actions repository be the first step of an action.

Actions that refer to each other assume that they have been checked out to the ./shared-actions folder. This should be the root of the GitHub Actions workspace. This assumption is what allow code reuse between actions.

Actions that use this pattern should include "dispatch" in their folder name, so that they can be readily distinguished from any actions that are either standalone or otherwise implementations that assume that the ./shared-actions folder is already cloned, so that they can use relative paths to reference other actions and files.

Example dispatch action

name: 'dispatch-example-action'
description: |
  The purpose of this wrapper is to keep it easy for external consumers to switch branches of
  the shared-actions repo when they are changing something about shared-actions and need to test it
  in their pipelines.

runs:
  using: 'composite'
  steps:
    - name: Clone shared-actions repo
      uses: actions/checkout@v4
      with:
        repository: ${{ env.SHARED_ACTIONS_REPO }}
        ref: ${{ env.SHARED_ACTIONS_REF }}
        path: ./shared-actions
    - name: Run local implementation action
      uses: ./shared-actions/impls/example-action

In this action, the "implementation action" is the ./shared-actions/impls/example-action. You can have inputs in your dispatch actions. You would just pass them through to the implementation action. Environment variables do carry through from the parent workflow through the dispatch action, and then into the implemetation action. In most cases, it is simpler (though less explicit) to set environment variables instead of plumbing inputs through each action.

Implementation action

These are similar to dispatch actions, except that they should not clone shared-actions. They can depend on other actions from the shared-actions repository using the ./shared-actions relative path.

name: 'example-action'
description: |
  An example of calling a python script in an action. Both the action
  and the python file are part of the shared-actions repo.

runs:
  using: 'composite'
  steps:
    - name: Run local action
      uses: ./shared-actions/impls/another-action
    - name: Run local script file
      run: python -c "./shared-actions/impls/hello.py"
      shell: bash

Example calling workflow

The key detail here is that the presence of the SHARED_ACTIONS_REPO and/or SHARED_ACTIONS_REF environment variables is what changes the shared-actions dispatch. The uses line should not change.

env:
  # Change these in PRs
  SHARED_ACTIONS_REPO: some-fork/shared-actions
  SHARED_ACTIONS_REF: some-custom-branch

jobs:
  actions-user:
    runs-on: ubuntu-latest
    steps:
      - name: Call dispatch example
        # DO NOT change the branch here (@main) in PRs
        uses: rapidsai/shared-actions/dispatch-example-action@main

This works because the environment variables get passed into the shared action. They are then used by the actions/checkout action, taking priority over the default values.

Calling in child shared workflows

Shared workflows complicate matters because environment variables do not get passed through. If you set the SHARED_ACTIONS_REPO and/or SHARED_ACTIONS_REF variables in the top-level parent workflow, they will not take effect in any dispatch actions that you may call in child workflows. You can pass them as inputs to child shared workflows, but that ends up being very verbose.

To carry this information into child workflows, we use a scheme that writes a file with environment variables, uploads this file as an artifact, then downloads and loads the file at the start of the child workflow.

The general scheme is:

Top-level workflow

jobs:
  setup-env-vars:
    runs-on: ubuntu-latest
    steps:
        # implicitly picks up env vars for SHARED_ACTIONS_REPO and _REF
        - uses: rapidsai/shared-actions/telemetry-dispatch-stash-base-env@main

  <rest of jobs>

  summarize-telemetry:
    needs: <all other jobs, or just pr-builder>
    # private networks will affect your choice here. If your tempo server or
    # forwarder/collector is only accessible on some node types, then use one of
    # those instances here
    runs-on: <node>
    steps:
      - uses: rapidsai/shared-actions/telemetry-dispatch-summarize@main

Child workflows

jobs:
  tests:
    strategy:
      matrix: ${{ fromJSON(needs.compute-matrix.outputs.MATRIX) }}
    runs-on: "linux-${{ matrix.ARCH }}-gpu-${{ matrix.GPU }}-${{ matrix.DRIVER }}-1"
    steps:
      - name: Telemetry setup
        uses: rapidsai/shared-actions/telemetry-dispatch-setup@main
        continue-on-error: true
        extra_attributes: "rapids.cuda=${{ matrix.CUDA_VER }},rapids.py=${{ matrix.PY_VER }}"

      <other steps, as usual>

Behind the scenes, the implementation actions are:

  • ./telemetry-impls/stash-base-env-vars: storing base environment variables (including setting default values):
  • ./telemetry-impls/load-then-clone: Downloads base env var file, loads it, then clones shared-actions according to env vars that were just loaded
  • ./telemetry-impls/summarize: Runs Python script to parse GitHub logs and send OpenTelemetry spans to endpoint

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

1 star

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages