GithubHelp home page GithubHelp logo

circleci-public / circleci-config-sdk-ts Goto Github PK

View Code? Open in Web Editor NEW
81.0 12.0 29.0 1.43 MB

Generate CircleCI Configuration YAML from JavaScript or TypeScript. Use Dynamic Configuration and the Config SDK together for live generative config.

Home Page: https://circleci-public.github.io/circleci-config-sdk-ts/

License: Apache License 2.0

TypeScript 99.08% JavaScript 0.42% Shell 0.49%
circleci ci javascript-sdk automation

circleci-config-sdk-ts's Introduction

CircleCI Config SDK

GitHub CircleCI npm codecov npm GitHub Repo stars

Create and manage your CircleCI configuration files with JavaScript and TypeScript.

Table of Contents

Getting Started

📖 Getting Started Wiki

📖 SDK API Docs

💻 Examples


Installation

Using npm:

$ npm i @circleci/circleci-config-sdk

Using yarn:

$ yarn add @circleci/circleci-config-sdk

Usage

In Browser:

import CircleCI from '@circleci/circleci-config-sdk';

In Node.js:

const CircleCI = require('@circleci/circleci-config-sdk');

Example

Generate a CircleCI config using TypeScript/Javascript, properly typed for full IntelliSense support.

const CircleCI = require('@circleci/circleci-config-sdk');
// Instantiate new Config
const myConfig = new CircleCI.Config();
// Create new Workflow
const myWorkflow = new CircleCI.Workflow('myWorkflow');
myConfig.addWorkflow(myWorkflow);

// Create an executor instance
// Executors are used directly in jobs
// and do not need to be added to the config separately
const nodeExecutor = new CircleCI.executors.DockerExecutor('cimg/node:lts');

// Create Job and add it to the config
const nodeTestJob = new CircleCI.Job('node-test', nodeExecutor);
myConfig.addJob(nodeTestJob);

// Add steps to job
nodeTestJob
  .addStep(new CircleCI.commands.Checkout())
  .addStep(
    new CircleCI.commands.Run({
      command: 'npm install',
      name: 'NPM Install',
    }),
  )
  .addStep(
    new CircleCI.commands.Run({
      command: 'npm run test',
      name: 'Run tests',
    }),
  );

// Add Jobs to Workflow
myWorkflow.addJob(nodeTestJob);

// The `stringify()` function on `CircleCI.Config` will return the CircleCI YAML equivalent.
const MyYamlConfig = myConfig.stringify();

// Save the config to a file in Node.js or the browser. Note, use in the browser requires user interaction.
myConfig.writeFile('config.yml');

MyYamlConfig will hold the following string (A valid CircleCI Config).

version: 2.1
setup: false
jobs:
  node-test:
    docker:
      - image: cimg/node:lts
    resource_class: medium
    steps:
      - checkout: {}
      - run:
          command: npm install
          name: NPM Install
      - run:
          command: npm run test
          name: Run tests
workflows:
  myWorkflow:
    jobs:
      - node-test: {}

Getting Help

This open-source project utilized GitHub issues and project boards to manage requests and support.

If you can not find an answer to your question in an existing issue, you may open a new issue with the appropriate template. Issues are the best way for the CircleCI team and the open-source community to track and interact with your questions.

Resources

Consider checking the following common resources before opening a new issue.

Contributing

This repository welcomes community contributions! See our CONTRIBUTING.md for guidance on configuring your development environment and how to submit quality pull requests.

Related

circleci-config-sdk-ts's People

Contributors

a-cordier avatar bear avatar circleci-secops avatar gray-wind avatar jaryt avatar jliby avatar kyletryon avatar mathieutu avatar mkusaka avatar tapesec avatar tatsuyayamamoto avatar timo-reymann avatar tste avatar vpanta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

circleci-config-sdk-ts's Issues

Bug: Parameters with typeof `steps` are not generated correctly

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Values passed to a parameter with the post_steps parameter type are generated incorrectly.

  • The builtin checkout command produces an empty object
  • A custom reusable command generates a name: property

This causes the generated config to fail when trying to run the pipeline

Minimum reproduction code

https://gist.github.com/Xavientois/21bb00fc854d75d3bab19905611d47a2

Steps to reproduce

No response

Expected behavior

  • Checkout would generate - checkout
  • The custom command would not include the name: property

CircleCI Config SDK version

0.10.1

Node.js version

16.18.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Feature: Multi-language support via aws/jsii

Enable support to utilize the CircleCI Config SDK with multiple target languages beyond TypeScript and JavaScript by utilizing aws/jsii.

Language Support

JSII build support is targeted for the 1.0.0 release of the CircleCI Config SDK. Language support is dependant on the current availability in the library.

Language Version
TypeScript 1.0.0
JavaScript 1.0.0
Python 1.0.0
Java 1.0.0
C# 1.0.0
Kotlin TBD
Go TBD

(https://aws.github.io/jsii/overview/features/#target-languages)

🚨 Blocking Issue 🚨

Current patterns utilized in the Config SDK which are appropriate for TypeScript are not available in the JSII build system due to compatibility with .NET Core 3.1.

In the current design, Components are extended from an abstract class where a generate() function is defined. This function will return the JSON schema of the component. Components such as jobs, commands, executors and workflows all extend Component, but each carry more specific definitions for their generate() function. This overriding of type of the generate() command is allowed in TypeScript as long as the types overlap, however in JSII this functionality is not available.

Issues on aws/jsii

Alternative Solutions:

An alternative design pattern must be considered to resolve the issue described above, allowing the use of JSII, without losing type defintions.

Bug: 0.12.1 is not published on npm

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

There is no 0.12.1 on npm. The latest version is still 0.12.0

https://www.npmjs.com/package/@circleci/circleci-config-sdk?activeTab=versions

Minimum reproduction code

N/A

Steps to reproduce

visit https://www.npmjs.com/package/@circleci/circleci-config-sdk?activeTab=versions

Expected behavior

It should have been published

CircleCI Config SDK version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Enhancement: Categorize types more appropriately

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Types are categorized by their components, and need to be broken up further.

Minimum reproduction code

n/a

Steps to reproduce

No response

Expected behavior

Categorized type exports

CircleCI Config SDK version

No response

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Feature: Support CircleCI 2.1 Config

Support CircleCI 2.1 Config

CircleCI 2.1 introduced reusable components and parameters, features that seek to emulate abilities provided by programming languages like JavaScript. Currently, the config SDK only supports 2.0 configuration.

Supporting certain features such as parameters in reusable executors has been proven difficult to implement and cumbersome to utilize as a user. However, we recognize the value in supporting 2.1 configuration abstraction so that existing 2.1 configs could be parsed, abstracted, and manipulated in the future.

Request: Investigate adding support for Python and other languages.

Investigation: Support multiple languages

There are many tools/libraries that may be able to assist in taking the existing TypeScript and either convert or interpret it for other languages.

Top Contender: aws/jsii

jsii allows code in any language to naturally interact with JavaScript classes. It is the technology that enables the AWS Cloud Development Kit to deliver polyglot libraries from a single codebase!

A class library written in TypeScript can be used in projects authored in TypeScript or Javascript (as usual), but also in C# (and other languages from the .NET family), Go, Java, Python, ... More languages will be added in the future!

Language Priority Notes
Python P0 Top user requested
Java P? No Requests
Go P? No Requests
.NET P? No Requests

Docs: Add complex 2.1 feature example to Wiki

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

No response

Describe the solution you'd like

Add an example config which displays a complex use case.

This should include all reusable types of config:

  • ParameterizedJob,
  • ReusableExecutor
  • CustomCommand and ReusableCommand

Teachability, documentation, adoption, migration strategy

n/a

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

n/a

Request: Please support self hosted runners as Executors

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

We use self hosted runners in our setup but to use them we need to set resource_class to an image name like cimg/go or whatever. Right now executors in the SDK are required to be and enumerated type (small, medium, large, etc.)

https://circleci.com/docs/resource-class-overview/#introduction

Describe the solution you'd like

It would be great to have a SelfHostedExecutor type that we could leverage.

my-self-hosted-executor:
    docker:
      - image: cimg/go:1.20
    resource_class: mynamespace/myrunner

Teachability, documentation, adoption, migration strategy

Just adding a new executor type should do. But it will require modifying the AnyResourceClass type to be able to support <namespace>/<runner> strings

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

As of right now There is no good way to represent this in code. My other option is to roll it into an orb and use it that way but it seems like overkill for this case.

Request: Reusable Executors

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Support reusable executors for the visual config editor

Describe the solution you'd like

--

Teachability, documentation, adoption, migration strategy

--

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

--

Request: add support for docker_layer_caching in machine executor

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

It looks like generating a machine executor from the SDK does not allow to define the docker_layer_caching property.

The MachineExecutorShape object defines this property, but it is not handled by the generateContent method in the executor itself.

Describe the solution you'd like

Maybe adding a useDockerImageLayerCaching method to the MachineExecutor class

export class MachineExecutor extends Executor<MachineResourceClass> {
  image = 'ubuntu-2004:202010-01';
  docker_layer_caching?: boolean;

  generateContents(): MachineExecutorShape {
    return {
      image: this.image,
      docker_layer_caching: this.docker_layer_caching,
    };
  }
  
  // [..]

  withDockerLayerCaching(activate: boolean): MachineExecutor {
    this.docker_layer_caching = activate;
    return this;
  }
}

Teachability, documentation, adoption, migration strategy

Enabling docker image layer caching on machine executors

const myConfig = new CircleCI.Config();
const machine = new CircleCI.executors.MachineExecutor('large').withDockerLayerCaching(true);
const const reusableMachine = new CircleCI.reusable.ReusableExecutor('default', machine);

myConfig.addReusableExecutor(reusableMachine);

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

We are considering using the SDK to generate our continuation step and need this feature to match our existing config file

Feature Request: Add comment to generated config with version of sdk

Beta Feedback

Add comment tag to generated config for easier support. The tag should specify the config has been automatically generated and include the version of the SDK which generated it.

Example

# This configuration file was generated by the CircleCI Config SDK
# CircleCI Config SDK version: 1.0.0

Request: Generate environment section for a job

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

I want to be able to specify environment variables within a job: https://circleci.com/docs/env-vars#setting-an-environment-variable-in-a-job

From what I can tell, this doesn't appear to be supported. I can add a step and define a parameter but I don't see a method for addEnvironment or defineEnvironment

Describe the solution you'd like

Essentially a new chainable method on a job where I can defineEnvironment

Teachability, documentation, adoption, migration strategy

job
.addStep(checkoutStep)
.defineParameter('a_parameter', 'string', 'value', 'description')
.defineEnvironment('A_ENV_VARIABLE', 'a value')

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

This is part of Circle CI and I am attempting to generate an existing yaml file using this library and I need the ability to specify environment variables.

Request: circle_ci_ip_ranges

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

No response

Describe the solution you'd like

Allow jobs to enable the circle_ci_ip_ranges features

Teachability, documentation, adoption, migration strategy

https://circleci.com/docs/2.0/configuration-reference/#circleciipranges

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

Parity with the configuration

Bug: Parse persist_to_workspace

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When parsing persist_to_workspace, the config reports that the native command cannot be found.

Minimum reproduction code

n/a

Steps to reproduce

No response

Expected behavior

Parse persist_to_workspace successfully

CircleCI Config SDK version

0.5.0

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Feature: Add Shell parameter to all executors

Feature Request

Add optional shell parameter

Describe the problem this feature would solve.

The Windows executor has the shell hard-set and may need to be modified.

Describe the ideal solution.

Extend the shell parameter to all executors with an appropriate default.

Request: Disable aliasDuplicateObjects by default

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

When inspecting the generated pipelines, duplicated parts (e.g. executors) are referenced using randomly generated anchors by the NPM YAML package.

This makes the pipelines harder to read and understand

Describe the solution you'd like

Default options for Config#stringify should set aliasDuplicateObjects to false

Teachability, documentation, adoption, migration strategy

Nothing to update / change

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

Make pipelines easier to read by default.

Request: accept async function as a job step or a workflow job

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Given a complex configuration with some custom generated jobs with specific step like this one:

import * as CircleCI from "@circleci/circleci-config-sdk";

// Components
const config = new CircleCI.Config();
const dockerExec = new CircleCI.executors.DockerExecutor("cimg/base:stable");
const workflow = new CircleCI.Workflow("main");

// Define "reusable" job, with native JS
type customJobParameters = {
  name: string;
  cluster: string;
  container_name: string;
  task_role: string;
};
const createCustomJob = (parameters: customJobParameters) => {
  const stepsToRun = [
    new CircleCI.commands.Checkout(),
    new CircleCI.commands.Run({ command: "echo 'Hello World'" }),
  ];

  // Add deploy step if tag
  // https://circleci.com/docs/variables/
  if (process.env.CIRCLE_TAG) {
    stepsToRun.push(new CircleCI.commands.Run({ command: "echo 'Deploying'" }));
  }
  return new CircleCI.Job(parameters.name, dockerExec, stepsToRun);
};

const jobDefinitions: customJobParameters[] = [
  {
    name: "job1",
    cluster: "cluster",
    container_name: "container_name",
    task_role: "task_role",
  },
  {
    name: "job2",
    cluster: "cluster",
    container_name: "container_name",
    task_role: "task_role",
  },
];

// Add jobs to workflow

jobDefinitions.forEach((jobDefinition) => {
  workflow.addJob(createCustomJob(jobDefinition));
});

config.addWorkflow(workflow);

// Print config
console.log(config.stringify());

I want to add a Step that can only be generated asynchronously. For example I want to send a slack notification that contains the git author. Something like:

const slackCommand = async () => {
  const author = await getAuthor() // async function with some git calls
  return new CircleCI.reusable.ReusedCommand(orbSlack.commands['notify'], {
    name: 'notify-author',
    event: 'fail',
    custom: JSON.stringify({
      text: `Commit by ${author}`,
    }),
  })
} 

For now, I have to make all the function call chain, asynchronous:

import * as CircleCI from '@circleci/circleci-config-sdk'

// Components
const config = new CircleCI.Config()
const dockerExec = new CircleCI.executors.DockerExecutor('cimg/base:stable')
const workflow = new CircleCI.Workflow('main')

// Asynchronous step
const createSlackCommand = async () => {
  const author = await getAuthor() // async function with some git calls
  return new CircleCI.reusable.ReusedCommand(orbSlack.commands['notify'], {
    name: 'notify-author',
    event: 'fail',
    custom: JSON.stringify({
      text: `Commit by ${author}`,
    }),
  })
}

// Define "reusable" job, with native JS
type customJobParameters = {
  name: string
  cluster: string
  container_name: string
  task_role: string
}
const createCustomJob = async (parameters: customJobParameters) => {
  const slackCmd = await createSlackCommand()
  const stepsToRun = [
    new CircleCI.commands.Checkout(),
    new CircleCI.commands.Run({command: "echo 'Hello World'"}),
    slackCmd,
  ]

  // Add deploy step if tag
  // https://circleci.com/docs/variables/
  if (process.env.CIRCLE_TAG) {
    stepsToRun.push(new CircleCI.commands.Run({command: "echo 'Deploying'"}))
  }
  return new CircleCI.Job(parameters.name, dockerExec, stepsToRun)
}

const jobDefinitions: customJobParameters[] = [
  {
    name: 'job1',
    cluster: 'cluster',
    container_name: 'container_name',
    task_role: 'task_role',
  },
  {
    name: 'job2',
    cluster: 'cluster',
    container_name: 'container_name',
    task_role: 'task_role',
  },
]

// Add jobs to workflow
async function main() {
  jobDefinitions.forEach(async jobDefinition => {
    workflow.addJob(await createCustomJob(jobDefinition))
  })

  config.addWorkflow(workflow)

  // Print config
  console.log(config.stringify())
}

main().catch(console.error)

Describe the solution you'd like

It would be awesome if steps array in Job constructor, accepts an array of Command OR async function that returns a Command.
It could lead to make this possible:

import * as CircleCI from '@circleci/circleci-config-sdk'

// Components
const config = new CircleCI.Config()
const dockerExec = new CircleCI.executors.DockerExecutor('cimg/base:stable')
const workflow = new CircleCI.Workflow('main')

// Asynchronous step
const createSlackCommand = async () => {
  const author = await getAuthor() // async function with some git calls
  return new CircleCI.reusable.ReusedCommand(orbSlack.commands['notify'], {
    name: 'notify-author',
    event: 'fail',
    custom: JSON.stringify({
      text: `Commit by ${author}`,
    }),
  })
}

// Define "reusable" job, with native JS
type customJobParameters = {
  name: string
  cluster: string
  container_name: string
  task_role: string
}
const createCustomJob = (parameters: customJobParameters) => {
  const slackCmd = createSlackCommand()
  const stepsToRun = [
    new CircleCI.commands.Checkout(),
    new CircleCI.commands.Run({command: "echo 'Hello World'"}),
    createSlackCommand,
  ]

  // Add deploy step if tag
  // https://circleci.com/docs/variables/
  if (process.env.CIRCLE_TAG) {
    stepsToRun.push(new CircleCI.commands.Run({command: "echo 'Deploying'"}))
  }
  return new CircleCI.Job(parameters.name, dockerExec, stepsToRun)
}

const jobDefinitions: customJobParameters[] = [
  {
    name: 'job1',
    cluster: 'cluster',
    container_name: 'container_name',
    task_role: 'task_role',
  },
  {
    name: 'job2',
    cluster: 'cluster',
    container_name: 'container_name',
    task_role: 'task_role',
  },
]

// Add jobs to workflow
jobDefinitions.forEach(jobDefinition => {
  workflow.addJob(createCustomJob(jobDefinition))
})

config.addWorkflow(workflow)

// Print config
console.log(config.stringify())

It would be very convenient to do the same with jobs array parameter for Workflow constructor.

Teachability, documentation, adoption, migration strategy

Typescript (and maybe example) would be enough to document it

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

With more powerful primitive for async job/command generation, it will help users to use more js mechanism instead of 2.1 yaml.

Bug: Typescript definition for Orb Import constructor doesn't match source

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

I have pulled down the current latest alpha version 0.9.0-alpha.16. I am attempting to add the slack orb and add a custom job for the notify_build_completion job. I used the unit test within the repo to recreate configuration of an OrbImport but I'm getting an error when I try to generate YAML:

Error: Error while parsing -
Missing type property on parameter: parameters
at errorParsing (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Config/exports/Parsing.ts:58:10)
    at parseParameter (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Components/Parameters/parsers/index.ts:52:13)
    at map (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Components/Parameters/parsers/index.ts:127:7)
    at Array.map (<anonymous>)
    at Object.parseParameterList (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Components/Parameters/parsers/index.ts:126:37)
    at map (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Orb/exports/OrbImport.ts:65:38)
    at Array.map (<anonymous>)
    at parseImportManifest (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Orb/exports/OrbImport.ts:64:44)
    at new t.OrbImport (/Users/johnmurphy/messaging-gateway/node_modules/@circleci/circleci-config-sdk/dist/webpack:/CircleCI/src/lib/Orb/exports/OrbImport.ts:43:19)
    at Object.<anonymous> (/Users/johnmurphy/messaging-gateway/.circleci/orbs/slack-orb.ts:13:25)

Minimum reproduction code

n/a

Steps to reproduce

  1. Pull down 0.9.0-alpha.16 from NPM
  2. View the type definitions for OrbImport
  3. Notice that the manifest parameter is optional and is listed after the version. In the source, manifest is not optional and is listed before the version

I think this is why the command is failing? Or that's my hunch anyway

Expected behavior

Adding a manifest with custom job parameters to an orb should not cause a crash and should instead generate YAML.

CircleCI Config SDK version

0.9.0-alpha.16

Node.js version

16.16.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

const manifest: types.orb.OrbImportManifest = {
  jobs: {
    notify_build_completion: new parameters.CustomParametersList([
      new parameters.CustomParameter('success_message', 'string'),
    ]),
  },
  commands: {},
  executors: {},
};
export const slackOrb = new orb.OrbImport(
  '',
  'circleci',
  'slack',
  '3.4.2',
  manifest,
);

Constructor of my type definition file:

constructor(alias: string, namespace: string, orb: string, version: string, manifest?: OrbImportManifest, description?: string, display?: OrbDisplayMeta);

Constructor of the source file:

constructor(
    alias: string,
    namespace: string,
    orb: string,
    manifest: OrbImportManifest,
    version: string,
    description?: string,
    display?: OrbDisplayMeta,
  ) 

Feature Request: Add pipeline parameters

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Users will want to access pipeline parameters that may have been set via the API, programmatically. These parameters can be used in code in logic statements or passed to 2.1 config elements.

Describe the solution you'd like

--

Teachability, documentation, adoption, migration strategy

--

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

--

Add failure condition testing

Current unit tests focus on verifying intended functionality. Expand testing to include testing to ensure failure conditions are validated.

ex:

  • What if a job is called from a workflow and has not yet been added to the config?

Failure testing should be limited to the framework and not attempt to re-implement config validation.

Feedback: Multiline commands are inconsistent

Version

0.4.0

Describe your experience

I've created a few steps with multiline command strings.

        new CircleCI.commands.Run({
            command: `blah
blah` }))

Some use the literal style | indicator and some use the chomping > indicator. What determines that and is it controllable?

Bug: Seemingly impossible to get a single `\` to appear in generated command text.

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Code Snippet

const BACKSLASH = `\\';
 new CircleCI.Job(
    jobName,
    new CircleCI.executors.DockerExecutor('cimg/python:3.11'),
    [
      BeanstalkOrb.setupCommand({}),
      new CircleCI.commands.Run({
        command: `
          set -ex
          cat${BACKSLASH}<<EOF>options.json
            [
              { "Namespace": "aws:autoscaling:asg", "OptionName": "MinSize",
                "Value": "${minInstances}" },
              { "Namespace": "aws:autoscaling:asg", "OptionName": "MaxSize",
                "Value": "${maxInstances}" }
            ]
          EOF`
      })
  ]);

When inside of a workflow will only ever generate an even number - 0, 2, 4, ... - of backslashes in the generated configuration - no matter the amount of backslashes included in BACKSLASH. This is making it impossible to generate the above command to execute during CI as it complains there is an unclosed << tag as that is a protected char/string by CircleCI.

Minimum reproduction code

See above.

Steps to reproduce

See above.

Expected behavior

It should be possible to get a single backslash to intentionally appear in generated text.

CircleCI Config SDK version

0.12.3

Node.js version

16.13.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Ensure browser release

Currently building for Node.JS. Need to make the package work for NodeJS + Web Browser

Request: aws_auth should support specifying an IAM role when fetching executor images from ECR

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Since the introduction of support for OIDC-tokens, CircleCI recommends using using OIDC tokens over Access Keys/Secrets.
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect

But looking at the docs at
https://circleci.com/docs/private-images/#aws-ecr
we can only specify a key/secret pair when fetching images from private ECR repos

aws_auth:
          aws_access_key_id: $AWS_ACCESS_KEY_ID_PRODUCTION
          aws_secret_access_key: $AWS_SECRET_ACCESS_KEY_PRODUCTION

Describe the solution you'd like

Support specifying a role-arn, similar to the example given here
https://circleci.com/docs/openid-connect-tokens/#adding-aws-to-the-circleci-configuration-file

Teachability, documentation, adoption, migration strategy

This change will allow users to follow security best practices as recommended by CircleCI.

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

Security. Users shouldn't be forced to use access keys and secrets when the rest of the CircleCI platform supports and recommends using OIDC tokens.

Request: Can this be used as an Orb SDK or not?

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

It is unclear to me if this can be used for orb development or not, but it appears that the current answer is: no.

Describe the solution you'd like

Using this SDK for Orb development.

Teachability, documentation, adoption, migration strategy

n/a

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

Comparable functionality to Jenkins shared libraries, Github Actions actions, Concourse custom resources, and other CI platforms that enable reusable portable library code across pipelines (currently absent from e.g. GitlabCI and TravisCI, but hopefully could exist in CircleCI).

Request: Add CommitLint

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Ensure all commits standardize to conventional commit standards.
https://github.com/conventional-changelog/commitlint

Describe the solution you'd like

Add a pre-commit hook via the commit-lint npm module to validate commits.
https://commitlint.js.org/#/

Teachability, documentation, adoption, migration strategy

Users will receive an error when making a new commit if conventional commit format is not followed.

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

To standardize the commit messages and make clean change-logs that can be parsed in the future.

Request: Example of accessing Pipeline parameters in Config SDK

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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?

  • Adapting config to external triggers
  • Providing more flexibility for dynamic configuring

Feature: Parse existing config

Parse CircleCI Config

Currently, the config SDK can only generate CircleCI config files. This request is to add parsing, so that existing config files can be abstracted to a CircleCIConfigObject so that they may be manipulated in code.

Why?

  • Visualize and edit existing config using the visual config editor
  • Access config programmatically from within an application

How?

Each Component has a generate() function currently which returns the JSON schema for said component. To reverse this process, we should add a parse() function which will return an instance of the component (like a factory) when given JSON schema input.

On the main config object, there is a function stringify() which loops through the config objects and calls the generate() function on each component to build the config. We will add a parse() function here as well which will do the opposite, and traverse the input config, generating the config object.

Refactor!: expand run command parameters

Currently, the constructor for the Run native command takes in a singular argument RunParameters, which is an object containing all possible parameters of the Run command.

While the singular argument for parameters in the constructor is preferred, we should expand the internal properties.

https://github.com/CircleCI-Public/circleci-config-sdk-ts/blob/main/src/lib/Components/Commands/exports/Native/Run.ts#L20

constructor(parameters: RunParameters) {
    this.parameters = parameters;
  }

This should be expanded into this instead.

/**
   * Command to run via the shell
   */
  command: StringParameter;
  /**
   * Shell to use for execution command (default: See Default Shell Options)
   */
  shell?: StringParameter;
...

Feature: Implement Validation At The Component Level

Implement Validation At The Component Level

Currently, though there is a type system in place, there is no config validation. In areas where specific string patterns are required for instance, typescript is only checking that the value is a string. Without any bindings to the CircleCI CLI currently, there is also no mechanism for validating CircleCI Configs generated with the SDK manually.

This issue proposes that each component implement its own validate() function which would be executed prior to a component's generate() function and throw an error with an appropriate resolution message. This would mean reimplementing all or a large portion of the same validation logic used in the CircleCI CLI. Opening for discussion.

Workflow.addJob should accept a WorkflowJob as an overload (or create addWorkflowJob)

addJob(job: Job, parameters?: WorkflowJobParameters): this {

Symptom

When referencing an orb, there is no convenient way to reference an orb-defined job inside of a Workflow using dot-chaining. Looking at test code, it appears the way an orb job should be used is to pass the OrbRef to the WorkflowJob constructor and set the required parameters.

Once this is done, however, the only way to supply the WorkflowJob to a workflow is via the constructor. This is awkward as it is not compatible with the addJob interface also provided by the class.

Feature request

Allow addJob to accept a WorkflowJob or create a function addWorkflowJob within Workflow. Whichever of these is chosen, there needs to be an argument that allows additional WorkflowJobParameters (such as context, name, or requires) to be passed in and added to the parameter list already present in the WorkflowJob.

Another option could be to create a ReusedJob similar to commands/executors.

Bug: Job parallelism property is not displayed

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

The parallelism option is supposed to available for a job.
This parallelism property is available into the Job class constructor but it is not passed to the generateContents method so you can’t see it in the final generated .yml config.

Minimum reproduction code

<script src="https://gist.github.com/tapesec/a2ba9bce9b2ca88542bd4cc05edca154.js"></script>

Steps to reproduce

No response

Expected behavior

The parallelism property passed to the Job class constructor is not returned from the generateContents method.
I added it.

CircleCI Config SDK version

v0.9.0-alpha.21

Node.js version

16.13.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Bug: Parameters default value mismatch it's type

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

CustomParameter generates an entry where default parameter is not quoted. That leads to type mismatch in result YAML, since some defaults like true, on, and off can be treated as booleans instead of strings.

new CircleCI.parameters.CustomParameter(
    'some_value',
    CircleCI.mapping.ParameterSubtype.STRING,
    "OFF"
)
parameters:
     some_value:
        type: string
        default: OFF

image

Config is not valid

% circleci config validate config.yml 

Error: Error in definition of command 'some-command'
Parameter error: default value of parameter 'some_value' is 'false' (type boolean): expected type string

Minimum reproduction code

https://gist.github.com/Kylmakalle/22f2c6eae2bd09758a70be2510284b33

Expected behavior

Any default provided value is "quoted" properly and aligns with parameter type.

CircleCI Config SDK version

0.12.0

Node.js version

19.0.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Bug: Executor generateContents method doesn’t return more than one image

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When you call the .generate method from an Executor instance and you have add more than one Image, the generate method returns only the first one.

Minimum reproduction code

https://gist.github.com/tapesec/5d25e351e6528426b16a91ef2360ee63

Steps to reproduce

No response

Expected behavior

The Executor instance should return as much ImageService as has been added.
Here is the link to the related Fix I’ve done

CircleCI Config SDK version

0.11.0

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Request: create conditional step

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

I'd like to write a ReusableCommand having a conditional step based on the value of the parameter:

parameters:
  tag:
    type: string
    default: ""

steps:
  - when:
      condition: <<parameters.tag>>
      steps:
        - run: |
            export TAG=<< parameters.tag >>
            echo "export TAG=$TAG" >> $BASH_ENV
  - unless:
      condition: <<parameters.tag>>
      steps:
        - run:
            name: Compute Tag
            command: |
              export TAG=$(echo "${CIRCLE_BRANCH:0:15}-${CIRCLE_SHA1:0:7}" | sed -E 's/[~^]+//g' | sed -E 's/[^a-zA-Z0-9]+/-/g' | sed -E 's/^-+|-+$//g' | tr A-Z a-z)
              echo "export TAG=$TAG" >> $BASH_ENV

Describe the solution you'd like

Something like:

new reusable.ReusableCommand(
    'my-command',
    [
        new When("<<parameters.tag>>", [
            new commands.Run({
                command: `export TAG=<< parameters.tag >>
                echo "export TAG=$TAG" >> $BASH_ENV`,
            }),
        ]),
        new Unless("<<parameters.tag>>", [
            new commands.Run({
                command: `export TAG=$(echo "\${CIRCLE_BRANCH:0:15}-\${CIRCLE_SHA1:0:7}" | sed -E 's/[~^]+//g' | sed -E 's/[^a-zA-Z0-9]+/-/g' | sed -E 's/^-+|-+$//g' | tr A-Z a-z)
                echo "export TAG=$TAG" >> $BASH_ENV`,
            }),
        ]),
    ],
    new parameters.CustomParametersList([
        new parameters.CustomParameter(
            "tag",
            "string",
            "",
        )
    ]),
);

Teachability, documentation, adoption, migration strategy

This would allow users to write ReusableCommand having a conditional step

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

To have consistency on how to write command with Yaml and SDK

Relocate Documentation To gh-pages

Move documentation to a new branch

Why?

Documentation is automatically generated at the time of release. We do not want/need commits added to the main repository for documentation. Documentation may later be moved to a separate repo altogether. For now, move docs to gh-pages

Request: Reusable Commands

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

Add reusable commands from 2.1

Describe the solution you'd like

--

Teachability, documentation, adoption, migration strategy

--

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

--

Bug: Parse Components with Undefined Parameters

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When parsing a component without a command does not have a body

Affects:

  • Job's
  • Steps

Workaround

Add an empty object to the body of the component
- checkout to - checkout: {}

Minimum reproduction code

N/A

Steps to reproduce

Parse a command or job

Expected behavior

Parse the config

CircleCI Config SDK version

0.5.0

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Bug: Error: Cannot find module '@circleci/circleci-config-sdk/dist/src/lib/Components/Executors/exports/DockerImage'

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

yarn run v1.22.17
$ ts-node index.ts -f ../../.circleci/config.yml
Error: Cannot find module '@circleci/circleci-config-sdk/dist/src/lib/Components/Executors/exports/DockerImage'
Require stack:
- /myproject/scripts/generate_circleci_config/index.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:995:15)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (myproject/scripts/generate_circleci_config/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30)
    at Function.Module._load (node:internal/modules/cjs/loader:841:27)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (myproject/scripts/generate_circleci_config/index.ts:2:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Module.m._compile (myproject/scripts/generate_circleci_config/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Object.require.extensions.<computed> [as .ts] (myproject/scripts/generate_circleci_config/node_modules/ts-node/src/index.ts:1621:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'myproject/scripts/generate_circleci_config/index.ts'
  ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Minimum reproduction code

https://gist.github.com/mstva/d2abbae90e9d60b4d485386bbe2f5832

Steps to reproduce

No response

Expected behavior

it should give me the job like this

version: 2.1
setup: false
jobs:
  run_unit_tests:
    docker:
      - image: cimg/python:3.10
      - image: cimg/postgres:13.8

CircleCI Config SDK version

0.11.1

Node.js version

18.11.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Request: Add save to file functionality to config

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

To use the SDK together with the continuation orb, you need a configuration file written to disk. This also stated in the README and getting started guide.

Saving the file to disk is something that I think a lot (if not most) of the users would find useful.

Describe the solution you'd like

Provide a way to save to disk with a method directly on the CircleCI configuration object.

The ideal solution would look like this:

const config = new CircleCI.Config();
// ... build configuration
try {
  await config.saveToDisk("fileName.yml");
} catch(e) {
  console.error("Failed to generate configuration", e);
  process.exit(1);
}

Under the hood, it just uses the fs module from Node.js to write the file to disk and wrapping the logic into a promise, making it easy to use.

Teachability, documentation, adoption, migration strategy

When the functionality is implemented, adjusting the getting started guide and the example should be sufficient.

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

Currently, it is required to copy & paste the logic block to all projects where dynamic pipelines are used, or otherwise an internal library is required.

To reduce this effort, it would be convenient to include this in the regular SDK.

Additional information

If the feature is something you folks from CircleCI see as useful and worth to include into the SDK, I would also happily create a PR :)

Request: Orb usage example (and addJob compatibility)

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

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

First of all, thank you for this awesome project.
I was frustrated to write a complex configuration with YAML (monorepo with conditional CI "path"). I was looking for a template engine to write a yaml file. And I found this! Mind blowing.

My configuration currently uses 6 orbs (jobs and command). And I am trying hard to use them with the sdk.
The only documentation is your test suite.

And the only way I found to use this orb job is:

const config = new Config()
const queueOrb = new orb.OrbImport('queue', 'eddiewebb', 'queue', 'volatile', '', {
  commands: {},
  jobs: {
    block_workflow: new parameters.CustomParametersList([
      new parameters.CustomParameter('time', 'string'),
      new parameters.CustomParameter('only-on-branch', 'string'),
    ]),
  },
  executors: {},
})

config.importOrb(queueOrb)

const job = new workflow.WorkflowJob(queueOrb.jobs['block_workflow'], {
  time: '15',
  'only-on-branch': 'master',
})

const myWorkflow = new Workflow('build', [job])

config.addWorkflow(myWorkflow)

This is not possible to use this (because of job parameter type):

myWorkflow.addJob(job)

Describe the solution you'd like

It would be awesome to have an example of how to use an Orb (job, command, executor).

And it would be great to use addJob like other jobs.
This is not ideal to declare the workflow at the end, and using a temporary (workflow.WorkflowJobAbstract | Job)[] array to store the jobs.

Teachability, documentation, adoption, migration strategy

This feature (documentation and addJob compatibility) will unlock some power usage, needed for the audience that needs this sdk

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

Using an orb job/command/executor as easier as a regular job/command/executor

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.