/circleci-dynamic-config-example

An example app in Rust for CircleCI's Dynamic Config demo

Primary LanguageRustMIT LicenseMIT

circleci-dynamic-config-example

An example app in Rust for CircleCI's dynamic config demo.

Dynamic config allows you to dynamically generate CircleCI's config depending on dynamic conditions.

This is useful especially for monorepos because you don't want to trigger all CircleCI workflows on every push.

About the example app

This is a client-server application in Rust.

The client code is also written in Rust and it generates WebAssembly files.

Here is the code structure:

Screen Shot 2022-10-05 at 14 30 11

Both client and server directories depends on the Rust library in shared directory.

Therefore we want to trigger CircleCI wofkflows under the following conditions:

  • Trigger client job when a new commit is pushed in client directory
  • Trigger server job when a new commit is pushed in server directory
  • Trigger all jobs when a new commit is pushed in shared directory

Setup

First of all, you need to enable dynamic config in CircleCI's project setting.

Go to [Project Settings] > [Advanced] and turn on Enable dynamic config using setup workflows.

Screen Shot 2022-10-05 at 14 34 02

You have to use CircleCI version 2.1 at the top of your .circleci/config.yml file.

version: 2.1

Also you need to add following lines in .circleci/config.yml to use dynamic config for the workflow.

setup: true

Configuration

For the monorepo use case, we have a path-filtering orb already available.

In order to use the orb, add the orbs stanza below your version.

orbs:
  path-filtering: circleci/path-filtering@0.1.3

Then you can map the updated files and directory to pipeline parameters

workflows:
  always-run:
    jobs:
      - path-filtering/filter:
          name: check-updated-files
          mapping: |
            client/.* run-build-client-job true
            server/.* run-build-server-job true
            shared/.* run-build-shared-job true
          base-revision: main
          config-path: .circleci/continue_config.yml

Note that the file specified in config-path is the dynamic config conditionally triggered. Then you can create .circleci/continue_config.yml and map the parameters like below

parameters:
  run-build-client-job:
    type: boolean
    default: false
  run-build-server-job:
    type: boolean
    default: false
  run-build-shared-job:
    type: boolean
    default: false

Finally you can declare workflows based on the conditions of the parameters.

workflows:
  client:
    when:
      or:
        [
          << pipeline.parameters.run-build-client-job >>,
          << pipeline.parameters.run-build-shared-job >>,
        ]
    jobs:
      - rust/lint-test-build:
          with_cache: false
          release: true
          version: 1.64.0
          working_directory: client
  server:
    when:
      or:
        [
          << pipeline.parameters.run-build-server-job >>,
          << pipeline.parameters.run-build-shared-job >>,
        ]
    jobs:
      - rust/lint-test-build:
          with_cache: false
          release: true
          version: 1.64.0
          working_directory: server
  shared:
    when: << pipeline.parameters.run-build-shared-job >>
    jobs:
      - rust/lint-test-build:
          with_cache: false
          release: true
          version: 1.64.0
          working_directory: shared

See .circleci directory for the complete example.

Trigger pipelines

You can add a file under server and push the commit.

$ cd server
$ touch test
$ git add test
$ git commit -m "feat: add test file to server"
$ git push

You can see only the server workflow is triggered.

Screen Shot 2022-10-05 at 14 48 27

You can also try adding a file under shared and push the commit.

$ cd shared
$ touch test
$ git add test
$ git commit -m "feat: add test file to shared"
$ git push

This time you can see all server, client and shared workflows are triggered.

Screen Shot 2022-10-05 at 14 48 37

Play

All Rust/Cargo command are wrapped by npm so please install npm packages first.

$ npm install

Then you can simply start server.

$ npm start

Open localhost:8080 you can test functions on both Server and Web Assembly

Screen Shot 2022-10-05 at 14 42 39