{"id":27424117,"url":"https://github.com/kiegroup/github-action-build-chain","last_synced_at":"2025-10-04T23:32:25.628Z","repository":{"id":37475243,"uuid":"282883152","full_name":"kiegroup/github-action-build-chain","owner":"kiegroup","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-28T10:10:49.000Z","size":4788,"stargazers_count":89,"open_issues_count":26,"forks_count":25,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-03T04:34:48.553Z","etag":null,"topics":["github","github-actions","hacktoberfest","workflow"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kiegroup.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-27T11:52:54.000Z","updated_at":"2025-03-26T13:27:34.000Z","dependencies_parsed_at":"2024-06-18T15:31:08.155Z","dependency_job_id":"5dee312e-b2be-4dff-9660-2fe986491eba","html_url":"https://github.com/kiegroup/github-action-build-chain","commit_stats":{"total_commits":260,"total_committers":15,"mean_commits":"17.333333333333332","dds":"0.35769230769230764","last_synced_commit":"14404f8658641e6bd3ade1b3fb563e39d79ce18e"},"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiegroup%2Fgithub-action-build-chain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiegroup%2Fgithub-action-build-chain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiegroup%2Fgithub-action-build-chain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kiegroup%2Fgithub-action-build-chain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kiegroup","download_url":"https://codeload.github.com/kiegroup/github-action-build-chain/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799934,"owners_count":21163404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github","github-actions","hacktoberfest","workflow"],"created_at":"2025-04-14T11:37:50.538Z","updated_at":"2025-10-04T23:32:20.584Z","avatar_url":"https://github.com/kiegroup.png","language":"TypeScript","readme":"# Github Action Build Chain\n\nGithub action build chain is a tool for github actions to build multiple projects from different repositories in a single action.\nThis tool is trying to solve the problem when a project depends on another project (most probably from the same organization) and one change can/should be performed in different repositories. How can we assure one specific pull request will work with the latest changes from/in the dependant/dependency projects and it won't break something? This is what we call **cross-repo pull requests** and **build-chain** is the way we have to solve it.\n\nLet's consider you have a project hierarchy like:\n\n![Project hierarchy](/docs/project-hierarchy.png)\n\nand you want to upstream/downstream build whatever project from this hierarchy, **Github Action Build Chain** provides you the mechanism to easily do it.\nYou can check [Usage example](#usage-example).\n\nJust defining the **build chain** flow in every project you want to trigger, the tool will get build information from `dependency-file` input and will execute every command from every project in a single github action.\n\nTable of content\n----------------\n\n* **[Github Action Build Chain](#github-action-build-chain)**\n* **[Build Chain Flows](#build-chain-flows)**\n* **[How to add it to your project(s)](#how-to-add-it-to-your-projects)**\n* **[Input Fields](#input-fields)**\n* **[Pre/Post sections](#prepost-sections)**\n* **[Archiving Artifacts](#archiving-artifacts)**\n* **[How to clone project in more than one folder](#how-to-clone-project-in-more-than-one-folder)**\n* **[Execution environment](#execution-environment)**\n* **[Usage example](#usage-example)**\n* **[Local Execution](#local-execution)**\n* **[About Commands to Execute](#about-commands-to-execute)**\n* **[v2 to v3](#v2-to-v3)**\n  * **[Using multiple git platforms](#using-multiple-git-platforms)**\n  * **[Found a regression?](#found-a-regression)**\n* **[Limitations](#limitations)**\n* **[Development](#development)**\n* **[System Requirements](#system-requirements)**\n\n\n## Allowed configuration files versions\n\n- 2.1\n- 2.2\n\n## Build Chain Flows\n\n### Cross Pull request flow\n\n- It checks out the current project and reads the workflow information from the YAML file triggering the job.\n\n  - It merges the TARGET_GROUP:PROJECT:TARGET_BRANCH into the SOURCE_GROUP:PROJECT:SOURCE_BRANCH from the pull request triggering the job.\n    \u003e **_Warning:_** It will fail in case it can't be done automatically, properly informing to please resolve conflicts.\n\n- It recursively checks out the rest of the dependant projects defined in `definition-file`.\n\n  - For each parent dependency:\n    - It will look for forked project belonging same github group as the one triggering the job.\n    - It will try to checkout SOURCE_GROUP:PROJECT:SOURCE_BRANCH. In case the it exists and it has a pull request over the TARGET_GROUP:PROJECT:TARGET_BRANCH it will check it out and will merge it with target branch.\n    - If previous checkout fails, it will try the same with TARGET_GROUP:PROJECT:SOURCE_BRANCH this time.\n    - If previous checkout fails, it will checkout TARGET_GROUP:PROJECT:TARGET_BRANCH.\n      \u003e **_Warning:_** It will fail in case it can't be done automatically, properly informing to please resolve conflicts.\n\n- Once all the projects are checked out, it will run as many commands are defined in `before`, `after` or root level properties from `build` section for every parent dependency starting from the highest level of the hierarchy to the lowest one.\n\n- It will archive artifacts in case `archive-artifacts-path` input is defined.\n\n### Full Downstream flow\n\n- It checks out the current project and reads the workflow information from the YAML file triggering the job.\n\n  - It merges the TARGET_GROUP:PROJECT:TARGET_BRANCH into the SOURCE_GROUP:PROJECT:SOURCE_BRANCH from the pull request triggering the job.\n    \u003e **_Warning:_** It will fail in case it can't be done automatically, properly informing to please resolve conflicts.\n\n- It gets the full downstream project chain (the parents projects plus its children and their dependencies. At the end the whole chain) based on configuration file.\n- It recursively checks out the rest of the dependant projects defined in `definition-file`.\n\n  - For each parent dependency:\n    - It will look for forked project belonging same github group as the one triggering the job.\n    - It will try to checkout SOURCE_GROUP:PROJECT:SOURCE_BRANCH. In case the it exists and it has a pull request over the TARGET_GROUP:PROJECT:TARGET_BRANCH it will check it out and will merge it with target branch.\n    - If previous checkout fails, it will try the same with TARGET_GROUP:PROJECT:SOURCE_BRANCH this time.\n    - If previous checkout fails, it will checkout TARGET_GROUP:PROJECT:TARGET_BRANCH.\n      \u003e **_Warning:_** It will fail in case it can't be done automatically, properly informing to please resolve conflicts.\n\n- Once all the projects are checked out, it will run as many commands are defined in `before`, `after` or root level properties from `build` section for every parent dependency starting from the highest level of the hierarchy to the lowest one.\n\n- It will archive artifacts in case `archive-artifacts-path` input is defined.\n\n### Single Pull Request flow\n\n- It checks out the current project and reads the workflow information from the YAML file triggering the job.\n\n  - It merges the TARGET_GROUP:PROJECT:TARGET_BRANCH into the SOURCE_GROUP:PROJECT:SOURCE_BRANCH from the pull request triggering the job.\n    \u003e **_Warning:_** It will fail in case it can't be done automatically, properly informing to please resolve conflicts.\n\n- Once the project from the event is checked out, it will run as many commands are defined in `before`, `after` or root level properties from `build` section.\n\n- It will archive artifacts in case `archive-artifacts-path` input is defined.\n\n### Branch flow\n\n- It checks out the whole tree from the `starting-project` project input and reads the workflow information from the YAML file triggering the job.\n\n- Once the projects from the branch are checked out, it will run as many commands are defined in `before`, `after` or root level properties from `build` section.\n\n- The flow will archive (in case the archiving is not skipped) a spreadsheet with the execution summary.\n\n## How to add it to your project(s)\n\nIt is just to add the step (replacing dependencies and commands):\n\n```\n- name: Build Chain ${{ matrix.java-version }}\n  id: build-chain\n  uses: ginxo/github-action-build-chain@BXMSPROD-1025\n  with:\n    definition-file: https://raw.githubusercontent.com/${GROUP}/droolsjbpm-build-bootstrap/${BRANCH}/.ci/pull-request-config.yaml\n  env:\n    GITHUB_TOKEN: \"${{ secrets.GITHUB_TOKEN }}\"\n```\n\nto your existing yaml flow definition or to create a new one. Do the same for the rest of the projects you need.\n\n\u003e **_Note:_** The `@actions/checkout` step is not needed since is the tool the one which is going to handle what to checkout for every project in the chain.\n\n## Input Fields\n\nSee [action.yml](action.yml)\n\n- **definition-file** (mandatory): `path to the file in filesystem | URL to the file`. [See more details](https://github.com/kiegroup/build-chain-configuration-reader#url-format)\n\n  \u003e Example:\n  \u003e\n  \u003e ```\n  \u003e definition-file: './folder/whatever_definition_file.yaml'\n  \u003e definition-file: 'http://yourdomain.com/definition-file.yaml'\n  \u003e definition-file: 'https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/main/.ci/pull-request-config.yaml'\n  \u003e definition-file: 'https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/${BRANCH}/.ci/pull-request-config.yaml'\n  \u003e definition-file: 'https://raw.githubusercontent.com/${GROUP}/droolsjbpm-build-bootstrap/${BRANCH}/.ci/pull-request-config.yaml'\n  \u003e definition-file: 'https://raw.githubusercontent.com/${GROUP}/${PROJECT_NAME}/${BRANCH}/.ci/pull-request-config.yaml'\n  \u003e ```\n\n\u003e **_Note:_** In case you use URL way, remember you should point the file content itself, so in case you want to use https://github.com/kiegroup/droolsjbpm-build-bootstrap/blob/a1efb55f17fd0fd9001b073c999e3fd2a80600a6/.ci/pull-request-config.yaml, `definition-file` value should be https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/a1efb55f17fd0fd9001b073c999e3fd2a80600a6/.ci/pull-request-config.yaml (Raw one for this case) or (using dynamic placeholders) https://raw.githubusercontent.com/${GROUP}/${PROJECT_NAME}/${BRANCH}/.ci/pull-request-config.yaml.\n\n- **flow-type** (optional. 'cross_pr' by default): The flow you want to execute. Possible values\n\n  - cross_pr: executes the cross pull request flow\n  - full_downstream: executes the full downstream flow\n  - branch: executes the branch flow\n  - single_pr: executes the single pull request flow\n\n- **starting-project** (optional. the project triggering the job by default): The project you want start building from. The project to construct the tree from. It's not the same as the project triggering the job which is taken from `GITHUB_REPOSITORY` env variable or the github pull request event payload. For instance\n\n  \u003e ```\n  \u003e starting-project: 'groupX/projectX' // it will get project dependencies tree from 'groupX/projectX'\n  \u003e starting-project: 'kiegroup/drools' // it will get project dependencies tree from 'kiegroup/drools'\n  \u003e ```\n\n  \u003e **_Note:_** You have to be sure the project tree to start building from, contains the project triggering the job.\n\n- **logger-level** (optional. 'info' by default): The log level. Possible values\n\n  - info\n  - trace\n  - debug\n\n  \u003e ```\n  \u003e logger-level: 'info'\n  \u003e logger-level: 'debug'\n  \u003e ```\n\n- **annotations-prefix** (optional. '' by default): The prefix to be shown on the Github Actions' Annotations title.\n\n  \u003e ```\n  \u003e annotations-prefix: \"${{ matrix.java-version }}/${{ matrix.maven-version }}\"\n  \u003e annotations-prefix: \"My Job Prefix\"\n  \u003e annotations-prefix: \"Gradle Version ${{ matrix.gradle-version }}\"\n  \u003e annotations-prefix: \"OS ${{ matrix.os }}\"\n  \u003e ```\n\n- **enable-parallel-execution** (optional. false by default): By enabling parallel execution, build-chain will try to detect projects that can be executed parallely without any conflicts i.e. no 2 projects where 1 depends on another will be executed parallely.\n\n- **additional-flags** (optional. '' by default): The chance to define additional flags for the execution, as it is done on the CLI side. Just semicolon (;) separated, like '--skipParallelCheckout;--skipExecution;-t (mvn .\\*)||\\$1 -s settings.xml'.\n\n  \u003e ```\n  \u003e additional-flags: \"--fullProjectDependencyTree\"\n  \u003e additional-flags: \"--fullProjectDependencyTree;--skipParallelCheckout\"\n  \u003e additional-flags: \"--skipParallelCheckout; --fullProjectDependencyTree\"\n  \u003e additional-flags: \"--skipParallelCheckout; -t (mvn .*)||$1 -s settings.xml\"\n  \u003e ```\n\n  \u003e **_Note:_** It has a limitation, the flag values can't contain semicolons (;), otherwise it will be treated as a new flag.\n\n## Pre/Post sections\n\nIt is possible to define pre and post sections in the definition-file. The idea is to have the chance to execute something before (`pre`) or after (`post`) project checkout and build command execution.\n\n### PRE\n\n```\npre: string | multiline string\n```\n\nIt will be executed even before checking out projects.\n\n#### Examples\n\n```\npre: export VARIABLE_NAME=value\n```\n\n```\npre: |\n  export VARIABLE_NAME=value\n  echo $VARIABLE_NAME\n```\n\n### POST\n\n```\npost:\n  success: string | multiline string\n  failure: string | multiline string\n  always: string | multiline string\n```\n\nIt will be executed after executing all commands for every project and after archiving artifacts. The options are:\n\n- `success`: it will be executed in case there's no error during build execution.\n- `failure`: it will be executed in case there's any error during build execution.\n- `always`: it will be always executed.\n\n#### Examples\n\n```\npost:\n  success: echo 'final message in case of no errors'\n  failure: echo 'final message in case of any error'\n  always: echo 'final message always printed'\n```\n\n```\npost:\n  success: |\n    echo 'final message in case of no errors 1'\n    echo 'final message in case of no errors 2'\n  failure: |\n    echo 'final message in case of any error'\n    echo 'final message in case of any error 2'\n  always: |\n    echo 'final message always printed'\n    echo 'final message always printed 2'\n```\n\n## Archiving Artifacts\n\nThe archive artifacts algorithm is basically copied from [actions/upload-artifact project](https://github.com/actions/upload-artifact) and (manually) transpiled to javascript. The usage is basically the same (the inputs are different named adding `archive-artifacts` prefix and the [Conditional Artifact Upload](https://github.com/actions/upload-artifact#conditional-artifact-upload) is not enabled), so why do we include this `archive artifacts` mechanism in this tool if it's already implemented by another tool? well, because this treats the archive artifacts mechanism for the whole build chain, so in case you define an `archive-artifacts-path` in a different project from the chain, all of them will be uploaded. If you are wondering if you are able to use `actions/upload-artifact` instead of the one we propose, the answer is 'yes', just take into consideration the artifacts will be archived based on the definition from the project triggering the job.\n\nThe `archive-artifacts-path` input brings you the chance to specify if the path will be uploaded in case of build success (default), in case of failure or always for every single path. For example specifying something like `path/to/artifact/world.txt@failure` will archive `path/to/artifact/world.txt` in case of execution failure. You can check [Upload for different execution results](https://github.com/actions/upload-artifact#upload-for-different-execution-results).\n\n### Upload an Individual File\n\n```yaml\narchive-artifacts:\n  path: **/dashbuilder-runtime.war\n```\n\n### Upload an Entire Directory\n\n```yaml\narchive-artifacts:\n  path: path/to/artifact-folder/\n```\n\n### Upload using a Wildcard Pattern\n\n```yaml\narchive-artifacts:\n  path: path/**/[abc]rtifac?/*\n```\n\n### Upload using Multiple Paths and Exclusions\n\n```yaml\narchive-artifacts:\n  path: |\n    path/output/bin/\n    path/output/test-results\n    !path/**/*.tmp\n```\n\n### Upload for different execution results\n\nThis is something additional to [@actions/glob](https://github.com/actions/toolkit/tree/main/packages/glob)\n\n```yaml\narchive-artifacts:\n  path: |\n    path/output/bin/\n    path2/output2/bin2/@success\n    path/output/test-results@failure\n    !path/**/*.tmp@always\n```\n\n- will upload `path/output/bin/` just in case of `success`\n- will upload `path2/output2/bin2/` just in case of `success`\n- will upload `path/output/test-results` just in case of `failure`\n- will upload `!path/**/*.tmp` in every case\n\n### Path Wildcards\n\nFor supported wildcards along with behavior and documentation, see [@actions/glob](https://github.com/actions/toolkit/tree/main/packages/glob) which is used internally to search for files.\n\nIf a wildcard pattern is used, the path hierarchy will be preserved after the first wildcard pattern.\n\n```\n    path/to/*/directory/foo?.txt =\u003e\n        ∟ path/to/some/directory/foo1.txt\n        ∟ path/to/some/directory/foo2.txt\n        ∟ path/to/other/directory/foo1.txt\n\n    would be flattened and uploaded as =\u003e\n        ∟ some/directory/foo1.txt\n        ∟ some/directory/foo2.txt\n        ∟ other/directory/foo1.txt\n```\n\nIf multiple paths are provided as input, the least common ancestor of all the search paths will be used as the root directory of the artifact. Exclude paths do not effect the directory structure.\n\nRelative and absolute file paths are both allowed. Relative paths are rooted against the current working directory. Paths that begin with a wildcard character should be quoted to avoid being interpreted as YAML aliases.\n\nThe [@actions/artifact](https://github.com/actions/toolkit/tree/main/packages/artifact) package is used internally to handle most of the logic around uploading an artifact. There is extra documentation around upload limitations and behavior in the toolkit repository that is worth checking out.\n\n### Customization if no files are found\n\nIf a path (or paths), result in no files being found for the artifact, the action will succeed but print out a warning. In certain scenarios it may be desirable to fail the action or suppress the warning. The `if-no-files-found` option allows you to customize the behavior of the action if no files are found.\n\n```yaml\narchive-artifacts:\n  path: path/to/artifact/\n  if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn`\n```\n\n### Conditional Artifact Upload\n\nnot supported (yet)\n\n### Uploading without artifact name\n\nYou can upload an artifact with or without specifying a name\n\n```yaml\narchive-artifacts:\n  name: my-artifacts\n  path: **/dashbuilder-runtime.war\n```\n\nIf not provided, `artifact` will be used as the default name which will manifest itself in the UI after upload.\n\n### Uploading to the same artifact\n\nEach artifact behaves as a file share. Uploading to the same artifact multiple times in the same workflow can overwrite and append already uploaded files\n\n```yaml\n# Project A\narchive-artifacts:\n  path: world.txt\n```\n\n```yaml\n# Project B\narchive-artifacts:\n  path: extra-file.txt\n```\n\n```yaml\n# Project C\narchive-artifacts:\n  path: world.txt\n```\n\nWith the following example, the available artifact (named `artifact` which is the default if no name is provided) would contain both `world.txt` and `extra-file.txt`.\n\n### Environment Variables and Tilde Expansion\n\nYou can use `~` in the path input as a substitute for `$HOME`. Basic tilde expansion is supported.\n\n```yaml\narchive-artifacts:\n  path: \"~/new/**/*\"\n```\n\n### archive-artifacts dependencies usage\n\nThe `dependencies` field allows us to define a set of projects for which we want to upload the artifacts.\n\n- `none` only artifacts from the starting project will be uploaded\n- `all` artifacts from all projects will be uploaded\n- `list of projects` artifacts from only a given list of projects will be uploaded\n\n```yaml\narchive-artifacts:\n  path: \"~/new/**/*\"\n  dependencies: \"none\"\n```\n\n```yaml\narchive-artifacts:\n  path: \"~/new/**/*\"\n  dependencies: \"all\"\n```\n\n```yaml\narchive-artifacts:\n  path: \"~/new/**/*\"\n  dependencies: |\n    projectX\n    projectY\n```\n\n## Where does the upload go?\n\nIn the top right corner of a workflow run, once the run is over, if you used this action, there will be a `Artifacts` dropdown which you can download items from. Here's a screenshot of what it looks like\u003cbr/\u003e\n\u003cimg src=\"docs/archive-artifacts-github.png\" width=\"375\" height=\"140\"\u003e\n\nThere is a trashcan icon that can be used to delete the artifact. This icon will only appear for users who have write permissions to the repository.\n\n## How to clone project in more than one folder\n\nIt is possible to clone project in more than one folder specifying `clone` field. For example:\n\n```\n  - project: kiegroup/appformer\n    clone:\n      - appformer-integration-test\n      - folderx/appformer-unit-test\n```\n\nwill clone the `kiegroup/appformer` in the `ROOT_FOLDER/PROJECT_FOLDER` and additionally will clone the project folder to `ROOT_FOLDER/PROJECT_FOLDER/appformer-integration-test` and `ROOT_FOLDER/PROJECT_FOLDER/folderx/appformer-unit-test`\n\nAnother example would be:\n\n```\n  - project: group/projectx\n    clone: another-folder\n```\n\nwill clone the `group/projectx` in the `ROOT_FOLDER/PROJECT_FOLDER` and additionally will clone the project folder to `ROOT_FOLDER/PROJECT_FOLDER/another-folder`\n\n\n## Execution environment\n\nThe environment execution definition is part of the workflow (the `.yml` file) and it depends on the commands you require to execute. If you require to execute maven commands you will have to add the `actions/setup-java@v1` with its java version, or in case you need python commands `actions/setup-python` is the one. You can find different examples in https://github.com/YOURGROUP/YOURPROJECT/actions/new.\n\nIt could be the case where you require a very specific environment to execute your stuff as it is the case for [python3-cekit](https://github.com/kiegroup/github-action-build-chain/tree/python3-cekit). Feel free to propose the environment you need as a pull request to this project:\n\n- Create a branch based on `python3-cekit` one\n- Modify [the Dockerfile from there](https://github.com/kiegroup/github-action-build-chain/blob/python3-cekit/Dockerfile)\n\nCurrent environments:\n\n- **python3-cekit**: python3 + python cekit library + docker + nodejs + yarn latest stable release [Dockerfile](https://github.com/kiegroup/github-action-build-chain/blob/python3-cekit/Dockerfile)\n\n## Usage example\n\nConsidering the projects hierarchy:\n\n![Project hierarchy](/docs/project-hierarchy.png)\n\nYou can check how to define build definition files from [Build Chain Configuration Reader documentation](https://github.com/kiegroup/build-chain-configuration-reader)\n\n### Mapping\n\nLet's suppose\n\n```\n- project: E\n  dependencies:\n    - project: D\n  mapping:\n    dependencies:\n      default:\n        - source: 7.x\n          target: main\n      C:\n        - source: main\n          target: 7.x\n        - source: 7.x\n          target: 7.x\n      D:\n        - source: main\n          target: 7.x\n        - source: 7.x\n          target: 7.x\n    dependant:\n      default:\n        - source: main\n          target: 7.x\n    exclude:\n      - A\n      - B\n```\n\n#### mapping.dependencies\n\nIt is used to define branch mapping between E and its dependencies in case `E` is `projectTriggeringTheJob`.\n\nIn case the `E:7.x` branch build or PR is triggered for this `7.x` target branch:\n\n- A: no mapping at all, so `7.x` (straight mapping) (since it is excluded)\n- B: no mapping at all, so `7.x` (straight mapping) (since it is excluded)\n- C:`7.x` (due to `mapping.dependencies.C` source `7.x` mapping)\n- D:`7.x` (due to `mapping.dependencies.D` source `7.x` mapping)\n- The rest (F,G,H,...): `main` (since `mapping.dependencies.default` mapping defined for source: `7.x`)\n\nIn case the `E:main` branch build or PR is triggered for this `main` target branch:\n\n- A: no mapping at all, so `main` (straight mapping) (since it is excluded)\n- B: no mapping at all, so `main` (straight mapping) (since it is excluded)\n- C:`7.x` (due to `mapping.dependencies.C` source `main` mapping)\n- D:`7.x` (due to `mapping.dependencies.C` source `main` mapping)\n- The rest (F,G,H,...): `main` (since there's no mapping defined for default main branch)\n\nIn case the `E:anyotherbranch` branch build or PR is triggered for this `anyotherbranch` target branch (being `anyotherbranch` whatever the branch name, except `7.x` or `main`):\n\n- No mapping at all, just straight mapping to `anyotherbranch`.\n\n#### mapping.dependant\n\nIt is used to define branch mapping between the rest of the projects and project A in case `E` is NOT `projectTriggeringTheJob`.\n\nIn case the `A:7.x` or any other (except `main`) branch build or PR is triggered -\u003e `E:7.x` will be taken (since there's not `mapping.dependant` for `7.x` source)\nIn case the `A:main` branch build or PR is triggered -\u003e `E:7.x` (due to `mapping.dependant.default` mapping)\n\n## Docker build\n\nYou can build the `github-action-build-chain` image locally with just executing docker command:\n\n```\ndocker build .\n```\n\nIn case you want to build it for a different openjdk version you just specify a `--build-arg OPENJDK_VERSION` argument:\n\n```\ndocker build --build-arg OPENJDK_VERSION=11 .\n```\n\n## Local execution\n\nIt's possible to use this tool locally, just follow this steps\n\n```\n$ npm install -g @kie/build-chain-action\n$ build-chain help\nUsage: build-chain [options] [command]\n\nA CLI tool to perform the build chain github actions\n\nOptions:\n  -h, --help      display help for command\n\nCommands:\n  build           Execute different flows\n  tools           A bunch of utility tools\n  help [command]  display help for command\n```\n\neither `sudo` and `env GITHUB_TOKEN=...` are optional depending on your local setup.\n\n\u003e Keep in mind: Whenever the tool is executed from a github check run, the `Printing local execution command` section is printed with the exact command you could copy/paste in order to reproduce it locally.\n\n### build command\n\nThe build command is used to execute the different flows locally\n\n```shell\n$ build-chain build help\nUsage: build-chain build [options] [command]\n\nExecute different flows\n\nOptions:\n  -h, --help                 display help for command\n\nCommands:\n  cross_pr [options]         Execute cross pull request build chain workflow\n  full_downstream [options]  Execute full downstream build chain workflow\n  single_pr [options]        Execute single pull request build chain workflow\n  branch [options]           Execute branch build chain workflow\n  help [command]             display help for command\n```\n\n### build command: cross_pr\n\nExecute pull-request flow\n\n```shell\n$ build-chain build cross_pr --help\nUsage: build-chain build cross_pr [options]\n\nExecute cross pull request build chain workflow\n\nOptions:\n  -u, --url \u003cevent_url\u003e                  pull request event url\n  -p, --startProject \u003cproject\u003e           The project to start the build from\n  -f, --defintionFile \u003cpath_or_url\u003e      The definition file, either a path to the filesystem or a URL to it\n  -o, --outputFolder \u003cpath\u003e              The folder path to store projects. Default is of the format 'build_chain_yyyymmddHHMMss' (default:\n                                         \"build_chain_202211229567\")\n  --token \u003ctoken...\u003e                     The GITHUB_TOKEN. It can be set as an environment variable instead. You can specify multiple tokens\n  -d, --debug                            Set debugging mode to true (default: false)\n  --skipExecution                        A flag to skip execution and artifacts archiving for all projects. Overrides skipProjectExecution (default:\n                                         false)\n  --skipProjectExecution \u003cprojects...\u003e   A flag to skip execution and artifacts archiving for certain projects only\n  --skipParallelCheckout                 Checkout the project sequentially (default: false)\n  --enableParallelExecution              Parallely execute projects (default: false)\n  -t, --customCommandTreatment \u003cexp...\u003e  Each exp must be of the form \u003cRegEx||ReplacementEx\u003e. Regex defines the regular expression for what you want\n                                         to replace with the ReplacementEx\n  --skipProjectCheckout \u003cprojects...\u003e    A list of projects to skip checkout.\n  --skipCheckout                         skip checkout for all projects. Overrides skipProjectCheckout (default: false)\n  -fae, --fail-at-end                    Only fail the build afterwards; allow all non-impacted builds to continue (default: false)\n  -h, --help                             display help for command\n```\n\nExample:\n\n```shell\n$ build-chain build cross_pr -f https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/main/.ci/pull-request-config.yaml -u https://github.com/kiegroup/kie-wb-distributions/pull/1068\n```\n\n### build command: full_downstream\n\nExecute full downstream (fdb) flow\n\n```shell\n$ build-chain build full_downstream --help\nUsage: build-chain build full_downstream [options]\n\nExecute full downstream build chain workflow\n\nOptions:\n  -u, --url \u003cevent_url\u003e                  pull request event url\n  -p, --startProject \u003cproject\u003e           The project to start the build from\n  -f, --defintionFile \u003cpath_or_url\u003e      The definition file, either a path to the filesystem or a URL to it\n  -o, --outputFolder \u003cpath\u003e              The folder path to store projects. Default is of the format 'build_chain_yyyymmddHHMMss' (default:\n                                         \"build_chain_2022112295741\")\n  --token \u003ctoken...\u003e                     The GITHUB_TOKEN. It can be set as an environment variable instead. You can specify multiple tokens\n  -d, --debug                            Set debugging mode to true (default: false)\n  --skipExecution                        A flag to skip execution and artifacts archiving for all projects. Overrides skipProjectExecution (default:\n                                         false)\n  --skipProjectExecution \u003cprojects...\u003e   A flag to skip execution and artifacts archiving for certain projects only\n  --skipParallelCheckout                 Checkout the project sequentially (default: false)\n  --enableParallelExecution              Parallely execute projects (default: false)\n  -t, --customCommandTreatment \u003cexp...\u003e  Each exp must be of the form \u003cRegEx||ReplacementEx\u003e. Regex defines the regular expression for what you want\n                                         to replace with the ReplacementEx\n  --skipProjectCheckout \u003cprojects...\u003e    A list of projects to skip checkout.\n  --skipCheckout                         skip checkout for all projects. Overrides skipProjectCheckout (default: false)\n  -fae, --fail-at-end                    Only fail the build afterwards; allow all non-impacted builds to continue (default: false)\n  -h, --help                             display help for command\n```\n\nExample:\n\n```shell\n$ build-chain build full_downstream -f https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/main/.ci/pull-request-config.yaml -u https://github.com/kiegroup/kie-wb-distributions/pull/1068\n```\n\n### build command: single_pr\n\nExecute single pr flow\n\n```shell\n$ build-chain build single_pr --help\nUsage: build-chain build single_pr [options]\n\nExecute single pull request build chain workflow\n\nOptions:\n  -u, --url \u003cevent_url\u003e                  pull request event url\n  -p, --startProject \u003cproject\u003e           The project to start the build from\n  -f, --defintionFile \u003cpath_or_url\u003e      The definition file, either a path to the filesystem or a URL to it\n  -o, --outputFolder \u003cpath\u003e              The folder path to store projects. Default is of the format 'build_chain_yyyymmddHHMMss' (default:\n                                         \"build_chain_2022112295912\")\n  --token \u003ctoken...\u003e                     The GITHUB_TOKEN. It can be set as an environment variable instead. You can specify multiple tokens\n  -d, --debug                            Set debugging mode to true (default: false)\n  --skipExecution                        A flag to skip execution and artifacts archiving for all projects. Overrides skipProjectExecution (default:\n                                         false)\n  --skipProjectExecution \u003cprojects...\u003e   A flag to skip execution and artifacts archiving for certain projects only\n  --skipParallelCheckout                 Checkout the project sequentially (default: false)\n  --enableParallelExecution              Parallely execute projects (default: false)\n  -t, --customCommandTreatment \u003cexp...\u003e  Each exp must be of the form \u003cRegEx||ReplacementEx\u003e. Regex defines the regular expression for what you want\n                                         to replace with the ReplacementEx\n  --skipProjectCheckout \u003cprojects...\u003e    A list of projects to skip checkout.\n  --skipCheckout                         skip checkout for all projects. Overrides skipProjectCheckout (default: false)\n  -fae, --fail-at-end                    Only fail the build afterwards; allow all non-impacted builds to continue (default: false)\n  -h, --help                             display help for command\n```\n\nExample: \n\n```shell\n$ build-chain build single_pr -f https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/main/.ci/pull-request-config.yaml -u https://github.com/kiegroup/kie-wb-distributions/pull/1068\n```\n\n### build command: branch\n\nExecute branch flow\n\n```shell\n$ build-chain build branch --help\nUsage: build-chain build branch [options]\n\nExecute branch build chain workflow\n\nOptions:\n  -p, --startProject \u003cproject\u003e           The project to start the build from\n  -b, --branch \u003cbranch\u003e                  The branch to get the project from\n  --fullProjectDependencyTree            Checks out and execute the whole tree instead of the upstream build (default: false)\n  -c, --command \u003ccommands...\u003e            The command(s) to execute for every project. This will override definition file configuration (just\n                                         dependency tree will be taken into account)\n  -g, --group \u003cgroup\u003e                    The group to execute flow. It will take it from project argument in case it's not specified\n  -f, --defintionFile \u003cpath_or_url\u003e      The definition file, either a path to the filesystem or a URL to it\n  -o, --outputFolder \u003cpath\u003e              The folder path to store projects. Default is of the format 'build_chain_yyyymmddHHMMss' (default:\n                                         \"build_chain_202211221013\")\n  --token \u003ctoken...\u003e                     The GITHUB_TOKEN. It can be set as an environment variable instead. You can specify multiple tokens\n  -d, --debug                            Set debugging mode to true (default: false)\n  --skipExecution                        A flag to skip execution and artifacts archiving for all projects. Overrides skipProjectExecution (default:\n                                         false)\n  --skipProjectExecution \u003cprojects...\u003e   A flag to skip execution and artifacts archiving for certain projects only\n  --skipParallelCheckout                 Checkout the project sequentially (default: false)\n  --enableParallelExecution              Parallely execute projects (default: false)\n  -t, --customCommandTreatment \u003cexp...\u003e  Each exp must be of the form \u003cRegEx||ReplacementEx\u003e. Regex defines the regular expression for what you want\n                                         to replace with the ReplacementEx\n  --skipProjectCheckout \u003cprojects...\u003e    A list of projects to skip checkout.\n  --skipCheckout                         skip checkout for all projects. Overrides skipProjectCheckout (default: false)\n  -fae, --fail-at-end                    Only fail the build afterwards; allow all non-impacted builds to continue (default: false)\n  -h, --help                             display help for command\n```\n\nExample:\n\n```shell\n$ build-chain build branch -f https://raw.githubusercontent.com/kiegroup/droolsjbpm-build-bootstrap/main/.ci/pull-request-config.yaml -p=kiegroup/lienzo-tests -b=main\n```\n\n### build command: resume\n\nThe `resume` command lets you continue your build from the last point of failure. When running any other `build-chain build` commands, it will produce a state file in the current working directory which will store all the data related to its execution. If you run `build-chain build resume` in the same working directory, then `build-chain` will pick up that state file, reconstruct `build-chain build`'s previous state and continue execution from the first point of failure. Note that the tokens are not stored in the state file, so you have to pass them again to the `resume` command using the `--token` option or setting them as env variables.\n\n```shell\n$ build-chain build resume --help\nUsage: build-chain build resume [options]\n\nResume execution from first point of failure in the previous execution\n\nOptions:\n  -w, --workspace \u003cworkspace\u003e   The workspace in which build chain was executed and the one to resume execution in (default: cwd)\n  -t, --token \u003ctoken\u003e           The GITHUB_TOKEN. It can be set as an environment variable instead\n  -d, --debug                   Set debugging mode to true (default: false)\n  -p, --startProject \u003cproject\u003e  Start from the given project instead of the first point of failure (default: false)\n  -c, --recheckout \u003cprojects...\u003e  List of projects to re-checkout and re-build (default: false)\n  -h, --help                    display help for command\n```\n\n#### Custom Command Replacement\n\nIt is possible to define custom expression to replace commands. The expression structure is `RegEx||ReplacementEx` where:\n\n- `RegEx`: you can define regular expression with or without literals. See [Javascript RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)\n- `||` just split `RegEx` from `ReplacementEx`\n- `ReplacementEx`: See [Javascript String replacement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace)\n\nSo basically at left side of `||` you define the regular expression where you want to apply string replacement from right side. For example, considering command `mvn clean install` in case we apply `(^mvn .*)||$1 -s ~/.m2/settings.xml` the final command will be `mvn clean install -s ~/.m2/settings.xml`\n\n### tool command\n\nThere are some utility tools as well\n\n```shell\n$ build-chain tools help\nUsage: build-chain tools [options] [command]\n\nA bunch of utility tools\n\nOptions:\n  -h, --help              display help for command\n\nCommands:\n  project-list [options]  Prints the projects that will be built given a starting project ordered by precedence\n  plan                    Execute build chain without actually cloning or executing projects (like a dry run)\n  resume [options]        Resume execution from first point of failure\n  help [command]          display help for command\n```  \n\n### tool command: plan\n\nThe `plan` command lets you execute build-chain without actually cloning or executing projects, like a dry run. This lets you verify whether build-chain will clone the correct projects, will checkout the correct branch, will merge the correct PRs and will execute the correct commands for each project. To use this command you simply have to pass the arguments that come after `build-chain build` command to `build-chain tools plan` command. For example:\n\nIf you want to see the dry run for the following `build` command:\n\n```shell\n$ build-chain build cross_pr -f definition_file -u event_url\n```\n\nthen, you have to run the following `plan` command:\n\n```shell\n$ build-chain tools plan cross_pr -f definition_file -u event_url\n```\n\n## About Commands to Execute\n\nJust consider the library used behind the scenes in order to execute commands is [@actions/exec](https://github.com/actions/toolkit/tree/main/packages/exec), this library has a limitation at https://github.com/actions/toolkit/blob/b5f31bb5a25d129441c294fc81ba7f92f3e978ba/packages/exec/src/exec.ts#L27 where it tries to decide the \"tool\" to be executed, so in case you need to execute bash or windows commands like conditionals you should use it like this\n\n### Bash\n`bash -c \"my command\"`\n`bash -c  \"if true; then echo 'it's TRUE'; else echo 'it's FALSE'; fi\"`\n\n### Windows\n`cmd /c \"my command\"`\n\n\u003e **_Note:_** thanks to https://github.com/actions/toolkit/issues/461#issuecomment-743750804\n\n# v2 to v3\n\nList of breaking changes from v2 to v3:\n\n- v2 flow types are deprecated but still supported. Since they are deprecated they might be removed in future releases. Acceptable v3 flowtypes which are consistent across CLI and github action are:\n  - cross_pr (know as pr or pull-request in v2)\n  - full_downstream (know as fd or fdb in v2)\n  - single_pr (know as single in v2)\n  - branch\n- v3 now accepts definition file version 2.2\n- CLI options that have changed:\n  - v2: `-df` to v3: `-f`\n  - v2: `-url` to v3: `-u` or `--url`\n  - v2: `-folder` to v3: `-o`\n  - v2: `-cct` to v3: `-t`\n  - v2: `-spc` to v3: `--skipProjectCheckout`\n  - v2: `-sp` to v3: `-p`\n- Project naming convention while checking out a project is now - `OWNER_PROJECT-NAME`. For example if we have `owner/some-name` the project will be checked out as `owner_some-name`. In v2 this would have been checked out as `owner_some_name`\n\n## Using multiple git platforms\n\nYou can now define multiple git platforms to clone your projects from. Currently only GitHub, GitLab and Gerrit are supported. Refer to [build-chain-configuration-reader](#https://github.com/kiegroup/build-chain-configuration-reader#platforms-only-in-version-23) on how to define multiple platforms. The advanatge of having this is that you can build projects that are hosted on one platform along with projects that are hosted on another platform.\n\nbuild-chain runs with a default platform configured. This default platform is used for projects which don't have a platform defined and for reading and loading configuration from the definition file.\n\nBy default, when you run build-chain as a github action the default platform configuration used is GitHub.  \n\nWhen using build-chain as a CLI tool, build-chain will try to detect the default platform based on the definition file url. If it is not able to detect it from the url, it will use GitHub as the default configuration. If you want to override all of this, you will have the option to define default configuration as CLI options (currently only GitHub and GitLab have default options):\n\n```shell\n-ghi, --defaultGithubId \u003cid\u003e                default github id\n-ghti, --defaultGithubTokenId \u003ctoken id\u003e    default github token id used to get token from env\n-gha, --defaultGithubApiUrl \u003capi url\u003e       default github api url to use\n-ghs, --defaultGithubServeUrl \u003cserver url\u003e  default github server url to use\n-gli, --defaultGitlabId \u003cid\u003e                default gitlab id\n-glti, --defaultGitlabTokenId \u003ctoken id\u003e    default gitlab token id used to get token from env\n-gla, --defaultGitlabApiUrl \u003capi url\u003e       default gitlab api url to use\n-gls, --defaultGitlabServeUrl \u003cserver url\u003e  default gitlab server url to use\n```\n\n### Multiple git platforms example\n\n```\nversion: 2.3\n\ndependencies:\n  - project: middleware/build-configurations\n    platform: rh-gitlab\n    mapping:\n      dependencies:\n        default:\n          - source: master\n            target: main\n      dependant:\n        default:\n          - source: main\n            target: master\n  - project: business-automation/eng-jenkins-scripts\n    platform: rh-gerrit\n    dependencies:\n      - project: middleware/build-configurations\n      - project: kiegroup/drools\n  \n  - project: kiegroup/drools\n    platform: github-public\n\ndefault:\n  build-command:\n    current: echo \"default current\"\n\nbuild:\n  - project: business-automation/eng-jenkins-scripts\n    build-command:\n      current: echo \"business-automation/eng-jenkins-scripts\"\n\nplatforms:\n  - id: rh-gitlab\n    type: gitlab\n    tokenId: RH_GITLAB_TOKEN\n    serverUrl: https://gitlab.xxxx.com\n    apiUrl: https://gitlab.xxxx.com/api/v4\n\n  - id: rh-gerrit\n    type: gerrit\n    tokenId: RH_GERRIT_TOKEN\n    serverUrl: https://gerrit.xxxx.com\n    apiUrl: https://gerrit.xxxx.com/r/a\n```\n\n\u003e **_Note:_** it is possible to specify as many github/gitlab/gerrit platforms as it is required\n\u003e **_Note:_** use `github-public`, `gitlab-public` and/or `gerrit-public` identifiers for `https://github.com`, `https://gitlab.com` and/or `https://gerrit.googlesource.com` respectively, no need to define them.\n\u003e **_Note:_** use `GITHUB_TOKEN`, `GITLAB_TOKEN` and/or `GERRIT_TOKEN` token for default github/gitlab/gerrit services.\n\n\n## Found a regression?  \n\nWe have a built a dynamic agonistic end to end regression testing suite to avoid breaking major features that were working in previous versions. Its dynamic since all the test cases are determined by a json file that anyone can update without knowing the details about the implementation. It is agnostic since it just cares about the final executable that is produced and is not implementation specific.\n\nIf you found a regression please add it to the test.json file is the below format:\n\n- For cli regression tests each test case is defined in [test/e2e-regression/cli/test.json](test/e2e-regression/cli/tests.json) in the format:\n\n```typescript\n{\n  name: string; // name of the test case. typically you can name it corresponding to the issue\n  cmd: string; // the build-chain cli command used to reproduce the issue\n  description?: string; // further description of the issue\n  env?: Record\u003cstring, string\u003e; // any env setup needed\n  shouldFail?: boolean; // whether the expected result after execution of build-chain is success or failure. by default it expects success\n  matchOutput?: string[] // any particular strings to match in the output\n  dontMatchOutput?: string[] // any particular strings we want to make sure aren't there in the output\n}\n```\n\n- For action regression tests each test case is defined in [test/e2e-regression/github-action/test.json](test/e2e-regression/github-action/test.json) in the format:\n\n```typescript\n{\n  name: string; // name of the test case. typically you can name it corresponding to the issue\n  event: string | PullRequestPayload; // it can either be a link to a PR or a JSON object similar to a pull request event payload\n  description?: string; // further description of the issue\n  env?: Record\u003cstring, string\u003e; // any env setup needed\n  shouldFail?: boolean; // whether the expected result after execution of build-chain is success or failure. by default it expects success\n  matchOutput?: string[] // any particular strings to match in the output\n  dontMatchOutput?: string[] // any particular strings we want to make sure aren't there in the output\n  \n  // it accepts all the inputs that are needed to run build-chain as a github action\n  \"definition-file\": string;\n  \"flow-type\": string;\n  \"starting-project?\": string;\n  \"skip-execution\"?: string;\n  \"skip-project-execution\"?: string;\n  \"skip-checkout\"?: string;\n  \"skip-project-checkout\"?: string;\n  \"skip-parallel-checkout\"?: string;\n  \"custom-command-treatment\"?: string;\n  \"additional-flags\"?: string;\n  \"logger-level\"?: string;\n  \"annotations-prefix\"?: string;\n}\n```\n# Limitations\n\n### Zipped Artifact Downloads\n\nDuring a workflow run, files are uploaded and downloaded individually using the `upload-artifact` and `download-artifact` actions. However, when a workflow run finishes and an artifact is downloaded from either the UI or through the [download api](https://developer.github.com/v3/actions/artifacts/#download-an-artifact), a zip is dynamically created with all the file contents that were uploaded. There is currently no way to download artifacts after a workflow run finishes in a format other than a zip or to download artifact contents individually. One of the consequences of this limitation is that if a zip is uploaded during a workflow run and then downloaded from the UI, there will be a double zip created.\n\n### Permission Loss\n\n:exclamation: File permissions are not maintained during artifact upload :exclamation: For example, if you make a file executable using `chmod` and then upload that file, post-download the file is no longer guaranteed to be set as an executable.\n\n### Case Insensitive Uploads\n\n:exclamation: File uploads are case insensitive :exclamation: If you upload `A.txt` and `a.txt` with the same root path, only a single file will be saved and available during download.\n\n## Github limitations\n\n### Using secrets on a forked project Github Action\n\nAccording to documentation, see [Workflows in forked repositories](https://docs.github.com/en/github-ae@latest/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)\n\n\u003e **_Note:_** With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository. The GITHUB_TOKEN has read-only permissions in forked repositories.\n\nNothing but `GITHUB_TOKEN` secret can be used from a forked project Github Action workflow. So cases like this will store nothing on `${{ env.GITHUB_TOKEN_GOOD_BAD }}`, `${{ env.CIFS_ZID_USER }}` or `${{ env.CIFS_ZID_KEY }}` but it will properly store `GITHUB_TOKEN` on `${{ env.GITHUB_TOKEN_GOOD}}`\n\n```\n      - name: \"Run build-chain\"\n        id: build-chain\n        uses: kiegroup/github-action-build-chain@main\n        with:\n          definition-file: whatever-the-file-url/path\n        env:\n          GITHUB_TOKEN_GOOD_BAD: \"${{ secrets.MY_GH_TOKEN }}\"\n          GITHUB_TOKEN_GOOD: \"${{ secrets.GITHUB_TOKEN }}\"\n          CIFS_ZID_USER: \"${{ secrets.CIFS_ZID_USER }}\"\n          CIFS_ZID_KEY: \"${{ secrets.CIFS_ZID_KEY }}\"\n```\n\n\u003e **_Note:_** Just remember this is not a problem from the tool itself but a limitation from Github Actions in order to avoid exposing sensitive information.\n\n### inputs usage in runs.image from action.yml\n\n\u003e Just in case you are interested in adapting this code or in case you want to create your own tool.\n\nIt's not possible to use expressions like `image: \"docker://kie-group:github-action-build-chain:{{ inputs.build-chain-build-system }}\"`. This way it would be easy to dynamically select image to run with a simple `with` input from flow yml file and we could skip errors like [matrix in uses](#matrix-in-uses).\nJust because of this we have to maintain different Dockerfile definitions in different branches and to tag every branch for every version we release like `python3-cekit-v1`.\n\n## Development\n\n### Execute CLI\n\n```\nnpm install\nnpm run build:cli\n./build/index.js build ...\n```\n\n### build-chain-configuration-reader dependency\n\nThe definition files are read thanks to [build-chain-configuration-reader](https://github.com/kiegroup/build-chain-configuration-reader) library so in case you want to modify something from there it's easier if you just [npm link](https://docs.npmjs.com/cli/link) it:\n\n- clone repository and browse to the folder\n- `npm install` it\n- (`sudo`) `npm link`\n- and then from this project folder execute `npm link @kie/build-chain-configuration-reader`  \n\n### Multi token usage with the help of octokit throttling  \n\nTo avoid rate limiting errors, users can pass in multiple tokens that octokit can use while making Github API calls.The idea is that when octokit gets a rate limit error for one token it will use another token from the pool and retry the same request.  \n\nTo implement this we used features and plugins from octokit itself. Using the [octokit throttling plugin](https://github.com/octokit/plugin-throttling.js), we attached hooks that are triggered whenever octokit gets a rate limit error. This hook switches out the current token with a new token from a whitelist pool of tokens (these tokens haven't reached their rate limit) and sets that token as the current token. The token which had reached its rate limit is then added to a blacklist where we keep track of after what time that token can become usable. Each time when this hook is triggered we also check whether a token from the blacklist is now available or not. If it is then we add it back to the whitelist for future use.\n\nNow since we have a dynamically changing current token, we had to create a custom auth strategy for octokit. This auth strategy also installs a hook which is triggered each time octokit makes a request. So before each request, this hook adds the current token to the authorization header.\n\n### Testing\n\n#### unit tests\nTo test your changes you can run\n```\nnpm test\n```\nAnd to test with coverage report you can run\n```\nnpm run test:report\n```\n#### e2e tests\n\nTo run e2e tests you need [Docker](https://docs.docker.com/get-docker/). Once you have setup docker you can run\n```\nnpm run test:e2e\n```\nTo generate log files containing the raw output of the worflows executed during e2e tests you can run\n```\nACT_LOG=true npm run test:e2e\n```\n\n# System Requirements\n\n* **Git** \u003e=2.28\n* **NodeJS** \u003e= 14\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiegroup%2Fgithub-action-build-chain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkiegroup%2Fgithub-action-build-chain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkiegroup%2Fgithub-action-build-chain/lists"}