├── .nvmrc ├── .prettierrc.json ├── .github ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE │ └── PULL_REQUEST.md └── ISSUE_TEMPLATE │ ├── FEATURE_REQUEST.yml │ └── BUG.yml ├── .gitignore ├── .husky └── pre-commit ├── examples ├── 01-Trigger-Workflow-On-Pull_Request │ ├── README.md │ ├── .github │ │ └── workflows │ │ │ └── main.yml │ └── .circleci │ │ └── config.yml └── 02-Trigger-Workflow-On-Release │ ├── README.md │ ├── .github │ └── workflows │ │ └── main.yml │ └── .circleci │ └── config.yml ├── .eslintrc.js ├── action.yml ├── package.json ├── index.js ├── README.md ├── CONTRIBUTING.md └── dist └── licenses.txt /.nvmrc: -------------------------------------------------------------------------------- 1 | v16.19.1 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @KyleTryon 2 | @CircleCI-Public/cpeng -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | .idea 4 | .vscode -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run lint && npm run format && npm run build 5 | -------------------------------------------------------------------------------- /examples/01-Trigger-Workflow-On-Pull_Request/README.md: -------------------------------------------------------------------------------- 1 | # 01 Trigger Workflow On Pull_Request 2 | 3 | Trigger your CircleCI pipelines on updates to a _pull_request_. 4 | 5 | https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#pull_request -------------------------------------------------------------------------------- /examples/02-Trigger-Workflow-On-Release/README.md: -------------------------------------------------------------------------------- 1 | # 02 Conditionally Trigger a Workflow on a GitHub Release 2 | 3 | Trigger a specific workflow when a _release_ is created. 4 | 5 | https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#release -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "es2021": true, 4 | "node": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parserOptions": { 8 | "ecmaVersion": 13, 9 | "sourceType": "module" 10 | }, 11 | "rules": { 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /examples/02-Trigger-Workflow-On-Release/.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: [published] 4 | jobs: 5 | trigger-circleci: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: 9 | id: 10 | uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0 11 | env: 12 | CCI_TOKEN: ${{ secrets.CCI_TOKEN }} -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Trigger CircleCI Pipeline' 2 | description: 'Trigger pipelines on CircleCI for any event on GitHub.' 3 | branding: 4 | icon: "check-circle" 5 | color: "green" 6 | inputs: 7 | GHA_Meta: 8 | required: false 9 | description: 'An optional additional metadata parameter. Will be available on the CircleCI pipeline as GHA_Meta' 10 | runs: 11 | using: 'node16' 12 | main: 'dist/index.js' 13 | -------------------------------------------------------------------------------- /examples/01-Trigger-Workflow-On-Pull_Request/.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | types: [opened, reopened, synchronize, assigned, edited] 4 | jobs: 5 | trigger-circleci: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: CircleCI Trigger on Pull Request 9 | id: 10 | uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0 11 | env: 12 | CCI_TOKEN: ${{ secrets.CCI_TOKEN }} -------------------------------------------------------------------------------- /examples/01-Trigger-Workflow-On-Pull_Request/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | ## 3 | # The config will be executed on each pull_request update due to the GitHub Workflow. 4 | # Each push will also trigger the config, due to default CircleCI's behavior. 5 | ## 6 | 7 | parameters: 8 | GHA_Actor: 9 | type: string 10 | default: "" 11 | GHA_Action: 12 | type: string 13 | default: "" 14 | GHA_Event: 15 | type: string 16 | default: "" 17 | GHA_Meta: 18 | type: string 19 | default: "" 20 | 21 | jobs: 22 | test: 23 | docker: 24 | - image: cimg/node:lts 25 | steps: 26 | - run: npm install 27 | - run: npm test 28 | 29 | workflows: 30 | test: 31 | # This workflow is set to be conditionally triggered, only when 32 | # the GitHub Action is triggered. 33 | # With no other workflows, normal push events will be ignored currently. 34 | when: << pipeline.parameters.GHA_Action >> 35 | jobs: 36 | - test 37 | -------------------------------------------------------------------------------- /examples/02-Trigger-Workflow-On-Release/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | ## 3 | # The `GHA_Event` parameter will be populated with the value `release` when triggered by 4 | # the GitHub workflow. This can be used in conditional statements to run a specific workflow 5 | # for a specific event. 6 | ## 7 | 8 | parameters: 9 | GHA_Event: 10 | type: string 11 | default: "" 12 | GHA_Actor: 13 | type: string 14 | default: "" 15 | GHA_Action: 16 | type: string 17 | default: "" 18 | GHA_Meta: 19 | type: string 20 | default: "" 21 | 22 | jobs: 23 | release: 24 | docker: 25 | - image: cimg/node:lts 26 | steps: 27 | - run: npm install 28 | - run: npm build 29 | - run: npm publish 30 | 31 | workflows: 32 | release: 33 | when: 34 | equal: [ "release", << pipeline.parameters.GHA_Event >> ] 35 | jobs: 36 | - release 37 | # This is mandatory to trigger a pipeline when pushing a tag 38 | filters: 39 | tags: 40 | only: /.*/ 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trigger-circleci-pipeline-gha", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "ncc build index.js --license licenses.txt", 9 | "lint": "eslint index.js", 10 | "format": "prettier --write index.js", 11 | "prepare": "husky install" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/CircleCI-Public/trigger-circleci-pipeline-action.git" 16 | }, 17 | "keywords": [], 18 | "author": "", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues" 22 | }, 23 | "homepage": "https://github.com/CircleCI-Public/trigger-circleci-pipeline-action#readme", 24 | "dependencies": { 25 | "@actions/github": "^5.1.1", 26 | "@actions/core": "^1.10.0", 27 | "axios": "^0.27.2" 28 | }, 29 | "devDependencies": { 30 | "@vercel/ncc": "^0.33.3", 31 | "eslint": "^8.12.0", 32 | "husky": "^7.0.0", 33 | "prettier": "2.5.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST.md: -------------------------------------------------------------------------------- 1 | ## PR Checklist 2 | Please check if your PR fulfills the following requirements: 3 | 4 | - [ ] The commit message follows our contributor [guidelines](https://github.com/CircleCI-Public/circleci-config-sdk-ts/blob/main/CONTRIBUTING.md). 5 | - [ ] Tests for the changes have been added (for bug fixes / features) 6 | - [ ] Documentation has been added or updated where needed. 7 | 8 | ## PR Type 9 | What kind of change does this PR introduce? 10 | 11 | 12 | 13 | - [ ] Bug fix 14 | - [ ] Feature 15 | - [ ] Code style update (formatting, local variables) 16 | - [ ] Refactoring (no functional changes, no api changes) 17 | - [ ] Build related changes 18 | - [ ] CI related changes 19 | - [ ] Other... Please describe: 20 | 21 | > more details 22 | 23 | ## What issues are resolved by this PR? 24 | 25 | - #[00] 26 | 27 | ## Describe the new behavior. 28 | 29 | 30 | > Description 31 | 32 | ## Does this PR introduce a breaking change? 33 | 34 | - [ ] Yes 35 | - [ ] No 36 | 37 | 38 | 39 | ## Other information 40 | 41 | 42 | > More information (optional) 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml: -------------------------------------------------------------------------------- 1 | name: "\U0001F4A1 Feature Request" 2 | description: Have an idea for a new feature? Begin by submitting a Feature Request 3 | title: 'Request: ' 4 | labels: [feature_request] 5 | # assignees: '' 6 | body: 7 | - type: checkboxes 8 | attributes: 9 | label: "Is there an existing issue that is already proposing this?" 10 | description: "Please search [here](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues?q=is%3Aissue) to see if an issue already exists for the feature you are requesting" 11 | options: 12 | - label: "I have searched the existing issues" 13 | required: true 14 | - type: textarea 15 | id: contact 16 | attributes: 17 | label: "Is your feature request related to a problem? Please describe it" 18 | description: "A clear and concise description of what the problem is" 19 | placeholder: | 20 | I have an issue when ... 21 | validations: 22 | required: false 23 | - type: textarea 24 | validations: 25 | required: true 26 | attributes: 27 | label: "Describe the solution you'd like" 28 | description: "A clear and concise description of what you want to happen. Add any considered drawbacks" 29 | - type: textarea 30 | validations: 31 | required: true 32 | attributes: 33 | label: "Teachability, documentation, adoption, migration strategy" 34 | description: "If you can, explain how users will be able to use this and possibly write out a version the docs." 35 | - type: textarea 36 | validations: 37 | required: true 38 | attributes: 39 | label: "What is the motivation / use case for changing the behavior?" 40 | description: "Describe the motivation or the concrete use case" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.yml: -------------------------------------------------------------------------------- 1 | name: "\U0001F41E Bug Report" 2 | description: Report any identified bugs. 3 | title: 'Bug: ' 4 | labels: [bug] 5 | # assignees: '' 6 | body: 7 | - type: checkboxes 8 | attributes: 9 | label: "Is there an existing issue for this?" 10 | description: "Please search [here](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues?q=is%3Aissue) to see if an issue already exists for the bug you encountered" 11 | options: 12 | - label: "I have searched the existing issues" 13 | required: true 14 | 15 | - type: textarea 16 | validations: 17 | required: true 18 | attributes: 19 | label: "Current behavior" 20 | description: "How does the issue manifest?" 21 | 22 | - type: input 23 | validations: 24 | required: true 25 | attributes: 26 | label: "Minimum reproduction code" 27 | description: "An URL to some git repository or gist which contains the minimum needed code to reproduce the error" 28 | placeholder: "https://github.com/..." 29 | 30 | - type: textarea 31 | attributes: 32 | label: "Steps to reproduce" 33 | description: | 34 | Detail the steps to take to replicate the issue. 35 | You may leave this blank if you have covered the issue in the minimum reproduction code above. 36 | placeholder: | 37 | 1. `npm i` 38 | 2. `npm start:dev` 39 | 3. See error... 40 | 41 | - type: textarea 42 | validations: 43 | required: true 44 | attributes: 45 | label: "Expected behavior" 46 | description: "A clear and concise description of what you expected to happen (or code)" 47 | 48 | - type: markdown 49 | attributes: 50 | value: | 51 | --- 52 | 53 | - type: input 54 | attributes: 55 | label: "GitHub Action Version" 56 | description: | 57 | Which version of `trigger-circleci-pipeline` are you using? 58 | placeholder: "1.0.0" 59 | 60 | - type: textarea 61 | attributes: 62 | label: "Other" 63 | description: | 64 | Anything else relevant? 65 | **Tip:** You can attach images, recordings or log files by clicking this area to highlight it and then dragging files in. 66 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { 2 | getInput, 3 | setFailed, 4 | setOutput, 5 | startGroup, 6 | endGroup, 7 | info, 8 | error as coreError, 9 | } from "@actions/core"; 10 | import { context } from "@actions/github"; 11 | import axios from "axios"; 12 | 13 | startGroup("Preparing CircleCI Pipeline Trigger"); 14 | const repoOrg = context.repo.owner; 15 | const repoName = context.repo.repo; 16 | info(`Org: ${repoOrg}`); 17 | info(`Repo: ${repoName}`); 18 | const ref = context.ref; 19 | 20 | const getBranch = () => { 21 | if (ref.startsWith("refs/heads/")) { 22 | return ref.substring(11); 23 | } else if (ref.startsWith("refs/pull/")) { 24 | info(`This is a PR. Using head PR branch`); 25 | const pullRequestNumber = ref.match(/refs\/pull\/([0-9]*)\//)[1]; 26 | const newref = `pull/${pullRequestNumber}/head`; 27 | return newref; 28 | } 29 | return ref; 30 | }; 31 | const getTag = () => { 32 | if (ref.startsWith("refs/tags/")) { 33 | return ref.substring(10); 34 | } 35 | }; 36 | 37 | const headers = { 38 | "content-type": "application/json", 39 | "x-attribution-login": context.actor, 40 | "x-attribution-actor-id": context.actor, 41 | "Circle-Token": `${process.env.CCI_TOKEN}`, 42 | }; 43 | const parameters = { 44 | GHA_Actor: context.actor, 45 | GHA_Action: context.action, 46 | GHA_Event: context.eventName, 47 | }; 48 | 49 | const metaData = getInput("GHA_Meta"); 50 | if (metaData.length > 0) { 51 | Object.assign(parameters, { GHA_Meta: metaData }); 52 | } 53 | 54 | const body = { 55 | parameters: parameters, 56 | }; 57 | 58 | const tag = getTag(); 59 | const branch = getBranch(); 60 | 61 | if (tag) { 62 | Object.assign(body, { tag }); 63 | } else { 64 | Object.assign(body, { branch }); 65 | } 66 | 67 | const url = `https://circleci.com/api/v2/project/gh/${repoOrg}/${repoName}/pipeline`; 68 | 69 | info(`Triggering CircleCI Pipeline for ${repoOrg}/${repoName}`); 70 | info(`Triggering URL: ${url}`); 71 | if (tag) { 72 | info(`Triggering tag: ${tag}`); 73 | } else { 74 | info(`Triggering branch: ${branch}`); 75 | } 76 | info(`Parameters:\n${JSON.stringify(parameters)}`); 77 | endGroup(); 78 | 79 | axios 80 | .post(url, body, { headers: headers }) 81 | .then((response) => { 82 | startGroup("Successfully triggered CircleCI Pipeline"); 83 | info(`CircleCI API Response: ${JSON.stringify(response.data)}`); 84 | setOutput("id", response.data.id); 85 | setOutput("number", response.data.number); 86 | setOutput("state", response.data.state); 87 | setOutput("created_at", response.data.created_at); 88 | endGroup(); 89 | }) 90 | .catch((error) => { 91 | startGroup("Failed to trigger CircleCI Pipeline"); 92 | coreError(error); 93 | setFailed(error.message); 94 | endGroup(); 95 | }); 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trigger CircleCI Pipeline 2 | 3 | Trigger your [CircleCI](https://circleci.com/) pipelines from any [event](https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows) on GitHub with [GitHub Actions](https://github.com/features/actions). 4 | 5 | # How to Use 6 | 7 | 1. Create a GitHub Action's workflow for the desired CircleCI pipeline. 8 | 9 | Do this by adding a workflow YAML file (we'll use `main.yml`) to `./.github/workflows`. 10 | 11 | A `release` trigger is shown in this example. Try any of the GitHub events for triggering workflows: 12 | https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows 13 | 14 | Select a custom name and id for the step for additional contextual metadata in your CircleCI pipeline 15 | 16 | ```yaml 17 | on: 18 | release: 19 | types: [published] 20 | jobs: 21 | trigger-circleci: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: 25 | id: 26 | uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0.5 27 | env: 28 | CCI_TOKEN: ${{ secrets.CCI_TOKEN }} 29 | ``` 30 | 31 | 2. Create an [encrypted secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) named `CCI_TOKEN` containing the [Personal API Token](https://circleci.com/docs/2.0/managing-api-tokens/) that will be used to trigger the pipelines. This is suggested to be a [machine user](https://docs.github.com/en/developers/overview/managing-deploy-keys#machine-users). 32 | 33 | 3. Add the [Pipeline Parameter](https://circleci.com/docs/2.0/pipeline-variables/) definitions to your CircleCI config. This data will be entered by the GitHub Action when triggered. 34 | 35 | Add the following to the top of your `.circleci/config.yml` file. Ensure you are specifying version `2.1` 36 | 37 | ```yaml 38 | version: 2.1 39 | parameters: 40 | GHA_Actor: 41 | type: string 42 | default: "" 43 | GHA_Action: 44 | type: string 45 | default: "" 46 | GHA_Event: 47 | type: string 48 | default: "" 49 | GHA_Meta: 50 | type: string 51 | default: "" 52 | ``` 53 | 54 | 4. Use the Pipeline Parameter data to run [workflows conditionally](https://circleci.com/docs/2.0/pipeline-variables/#conditional-workflows). 55 | 56 | **_See: [Examples](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/tree/main/examples)_** 57 | 58 | # Inputs 59 | 60 | Optional [input parameters](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs) that allow you to specify additional metadata. 61 | 62 | ### GHA_Meta 63 | 64 | **required:** false 65 | 66 | **description**: An optional additional metadata parameter. Will be available on the CircleCI pipeline as GHA_Meta. 67 | 68 | ```yaml 69 | jobs: 70 | trigger-circleci: 71 | runs-on: ubuntu-latest 72 | steps: 73 | - name: 74 | id: 75 | uses: CircleCI-Public/trigger-circleci-pipeline-action@v1.0.5 76 | with: 77 | GHA_Meta: "" 78 | env: 79 | CCI_TOKEN: ${{ secrets.CCI_TOKEN }} 80 | ``` 81 | 82 | # Things To Know 83 | 84 | ## GitHub Actions runs _alongside_ native CircleCI integration. 85 | 86 | By default, when a repository is connected to CircleCI, if the workflows within that project's configuration does not specify any conditionals or filters that would otherwise prevent execution, the workflow will execute on every `push` event by default. 87 | 88 | This may mean it is possible to accidentally run a job twice, once on the `push` event from CircleCI, as well as other events triggered by the GitHub Action. 89 | 90 | ### To prevent double execution 91 | 92 | If you are relying on GitHub Actions to provide all of your API triggers, ensure that each of your CircleCI configuration's workflows contains a [conditional](https://circleci.com/docs/2.0/pipeline-variables/#conditional-workflows) limiting it's execution to only the GitHub Action trigger. 93 | 94 | **Example** 95 | 96 | ```yaml 97 | workflows: 98 | # This workflow is set to be conditionally triggered, 99 | # only via the GitHub Action. 100 | # With no other unfiltered workflows, normal push events will be ignored. 101 | test: 102 | when: << pipeline.parameters.GHA_Action >> 103 | jobs: 104 | - test 105 | ``` 106 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for considering to contribute to the CircleCI Config SDK! Before you 4 | get started, we recommend taking a look at the guidelines belowL 5 | 6 | - [Have a Question?](#question) 7 | - [Issues and Bugs](#issue) 8 | - [Feature Requests](#feature) 9 | - [Contributing](#contribute) 10 | - [Submission Guidelines](#guidelines) 11 | - [Release Process](#release) 12 | 13 | ## Have a Question? 14 | 15 | ### I have a general question about CircleCI or CircleCI's `config.yml` file. 16 | 17 | Contact CircleCI's general support by filing a ticket here: 18 | [Submit a request](https://support.circleci.com/hc/en-us/requests/new) 19 | 20 | 21 | ## Discover a Bug? 22 | 23 | Find an issue or bug? 24 | 25 | You can help us resolve the issue by 26 | [submitting an issue](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues) 27 | on our GitHub repository. 28 | 29 | Up for a challenge? If you think you can fix the issue, consider sending in a 30 | [Pull Request](#pull). 31 | 32 | ## Missing Feature? 33 | 34 | Is anything missing? 35 | 36 | You can request a new feature by 37 | [submitting an issue](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues) 38 | to our GitHub repository, utilizing the `Feature Request` template. 39 | 40 | If you would like to instead contribute a pull request, please follow the 41 | [Submission Guidelines](#guidelines) 42 | 43 | ## Contributing 44 | 45 | Thank you for contributing to the CircleCI Config SDK! 46 | 47 | Before submitting any new Issue or Pull Request, search our repository for any 48 | existing or previous related submissions. 49 | 50 | - [Search Pull Requests](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/pulls?q=) 51 | - [Search Issues](https://github.com/CircleCI-Public/trigger-circleci-pipeline-action/issues?q=) 52 | 53 | ### Submission Guidelines 54 | 55 | #### Commit Conventions 56 | 57 | This project strictly adheres to the 58 | [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) 59 | specification for creating human readable commit messages with appropriate 60 | automation capabilities, such as changelog generation. 61 | 62 | ##### Commit Message Format 63 | 64 | Each commit message consists of a header, a body and a footer. The header has a 65 | special format that includes a type, a scope and a subject: 66 | 67 | ``` 68 | (optional ): 69 | 70 | 71 | 72 |