CircleCI-Public / circleci-config-sdk-ts

Generate CircleCI Configuration YAML from JavaScript or TypeScript. Use Dynamic Configuration and the Config SDK together for live generative config.
https://circleci-public.github.io/circleci-config-sdk-ts/
Apache License 2.0
82 stars 29 forks source link

Request: Example of accessing Pipeline parameters in Config SDK #171

Closed Kylmakalle closed 1 year ago

Kylmakalle commented 1 year ago

Is there an existing issue that is already proposing this?

Is your feature request related to a problem? Please describe it

I'm unable to find a way to access pipeline parameters in JS/TS code. I see there're some implementations related to Git or VCS project itself, but I was unable to access any custom parameters during setup stage. That being said, I also assume that any parameters that were passed to the pipeline trigger should be exposed in setup config, since CircleCI will raise a warning ⚠️ Unexpected argument(s): foo, even if it is stated in the dynamically generated config.

image

Describe the solution you'd like

Such as config.pipeline.git(), we can have a config.pipeline.parameters(), which I expect to be a dictionary of parameters or even something more type-safe.

Teachability, documentation, adoption, migration strategy

.

What is the motivation / use case for changing the behavior?

KyleTryon commented 1 year ago

Hello @Kylmakalle. While I would like to support pipelines eventually (and they are currently defined), it is not possible today to get the pipeline values from within the job. CircleCI's pipeline parameters are a config-level construct that is "processed" out before the config is actually run. The code that is executed within a job unfortunately has no knowledge of a pipeline or pipeline parameter. We would like to get there at some point but it may require some changes outside this SDK. We may look to remove it from the SDK for the time-being to avoid confusion, thank you for pointing that out.

What use-case were you attempting? From my experimentation, what I would recommend is setting any similar type values to environment variables, which will be available at runtime.

example:

version: 2.1
orbs:
  continuation: circleci/continuation@0.3.1
  node: circleci/node@5.0.2
setup: true
parameters:
  my-pipeline-parameter:
    type: string
    default: "foo/bar"
jobs:
  generate-config:
    executor: node/default
    environment:
        PARAM_PIPELINE_VALUE: <<pipeline.parameters.my-pipeline-parameter>>
    steps:
      - checkout
      - node/install-packages:
          app-dir: .circleci/dynamic
      - run:
          name: Generate config
          command: node .circleci/dynamic/index.js

This will populate PARAM_PIPELINE_VALUE with the value you are looking for. Then you can reference it as:

process.env.PARAM_PIPELINE_VALUE
Kylmakalle commented 1 year ago

Thank you @KyleTryon! It takes time to switch our minds between compile-time and run-time logic. Just so you know, I have one more approach.

The crucial thing there is to use your config.yaml to expose parameters during "compile-time" into your job execution environment in a way your code can consume them in a "run-time"

parameters:
  some_string_parameter:
    type: string
    default: foobar
  some_string_regex_parameter:
    type: string
    default: "^v[0-9]+\\.[0-9]+\\.[0-9]+.*$" 
  some_int_parameter:
    type: string
    default: 0
  some_bool_parameter:
    type: string
    default: false

steps:
    - run:
        name: Write repo parameters
        command: |
          # Please, mind the quotes for string-typed parameters and non-existence of quotes for other types.
          cat \<<'EOF' > repo_parameters.json
          {
              "some_string_parameter": "<< pipeline.parameters.some_string_parameter >>",
              "some_string_regex_parameter": "<< pipeline.parameters.some_string_regex_parameter >>",
              "some_int_parameter": << pipeline.parameters.some_int_parameter >>,
              "some_bool_parameter": << pipeline.parameters.some_bool_parameter >>
          }
          EOF
    - run: <your_script> repo_parameters.json