# Using CircleCI to generate GitHub repos within a job

**URL:** <https://discuss.circleci.com/t/using-circleci-to-generate-github-repos-within-a-job/39503>\
**Category:** Support Solutions\
**Created:** [March 22, 2021, 5:06pm UTC](https://discuss.circleci.com/t/using-circleci-to-generate-github-repos-within-a-job/39503 "2021-03-22T17:06:42Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![nbialostosky](https://sea2.discourse-cdn.com/circleci/user_avatar/discuss.circleci.com/nbialostosky/32/24962_2.png) [@nbialostosky](https://discuss.circleci.com/u/nbialostosky)\
**Post date:** [March 22, 2021, 5:06pm UTC](https://discuss.circleci.com/t/using-circleci-to-generate-github-repos-within-a-job/39503/1 "2021-03-22T17:06:42Z")

</div>

# Using CircleCI to generate GitHub repos within a job

I found myself needing to generate new repositories a lot, usually around testing. This required the creation of the repo, an initial commit including a valid CircleCI config, and then setting up the project in CircleCI.

With a little legwork I setup a CircleCI project that will take a pipeline create API call, with optional parameters, that then:

1. Creates a new GitHub repository
2. Based on optional parameters adds proper files and commits them to the repo (i.e. a `README` and basic CircleCI `config.yml`)
3. Kicks off the first build in CircleCI
4. Invites collaborators to the repository

The end result is a completely new test repository all correctly setup and ready to go – all from a single quick API call.

### Requirements

1. This guide utilizes Pipeline parameters, so you will need to be on at least version `2.1`
2. You will need a [personal access GitHub token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) with the “repo” scope
3. You will need a [personal CircleCI API token](https://circleci.com/docs/2.0/managing-api-tokens/#creating-a-personal-api-token)

### Configure Environment Variables

The commands that are run in the job that generates the repo require some environment variables to be set. These can be done at the [project level](https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-project), or, if you plan to use it across projects – [set these up in a context](https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-context).

| Variable Name | Description |
| --- | --- |
| CIRCLE\_TOKEN | This will be a [personal API token](https://circleci.com/docs/2.0/managing-api-tokens/#creating-a-personal-api-token). |
| ACCESS\_TOKEN | A generated [GitHub personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) that has the ‘repo’ scope. |

### Setup the repository that will generate the new testing repos

1. Add the `config.yml` file you are going to add to the newly created repository, this will be added at the root, I am calling mine `create-config.yml` with the following contents:

```auto
version: 2.1

jobs:
  setup:
    docker:
      - image: cimg/base:stable
    steps:
      - run: echo "hi"
  test:
    docker:
      - image: cimg/base:stable
    steps:
      - run: echo "hi"

workflows:
  version: 2
  setup-and-test:
    jobs:
      - setup
      - test:
          requires:
            - setup

```

1. Add a `README.md` file you are going to add to the newly created repository, I am adding mine to the root with the following contents:

```auto
### This is a repo for testing

See the [documentation](https://circleci.com/docs/2.0/) on how to utilize CircleCI!

```

1. Create a `.circleci` directory at the root.
2. Within `.circleci` directory create a `config.yml` file, within that file save the following contents:

```auto
version: 2.1

parameters:
  repo-name:
    type: string
    default: testing-demo
  collaborator:
    type: string
    default: none
  api-call:
    type: boolean
    default: false

jobs:
  generate-repo:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: Create new repo
          command: |
            curl -H "Authorization: token $ACCESS_TOKEN" --data '{"name":"<< pipeline.parameters.repo-name >>"}' https://api.github.com/user/repos
      - run:
          name: Add and commit config
          command: |
            git clone https://$ACCESS_TOKEN@github.com/nbialostosky/<< pipeline.parameters.repo-name >>.git
            cd << pipeline.parameters.repo-name >>
            git config --global user.email "test@example.com"
            git config --global user.name "nick bialostosky"
            touch README.md
            cp ~/project/README.md README.md
            mkdir .circleci
            cd .circleci
            touch config.yml
            cp ~/project/create-config.yml config.yml
            cd ..
            git add .
            git commit -m "add init config"
            git config push.default current
            git push
      - run:
          name: Setup project in circleci
          command: |
            curl --location --request POST 'https://circleci.com/api/v1.1/project/github/nbialostosky/<< pipeline.parameters.repo-name >>/follow' \
            --header 'Content-Type: application/json' \
            -u "$CIRCLE_TOKEN:" \
            --data-raw '{
              "first_build": "true"
            }'
      - run:
          name: Optionally add colaborator
          command: |
            if ["<< pipeline.parameters.collaborator >>" != "none"]; then
              curl -H "Authorization: token $ACCESS_TOKEN" "https://api.github.com/repos/nbialostosky/<< pipeline.parameters.repo-name >>/collaborators/<< pipeline.parameters.collaborator >>" -X PUT -d '{"permission":"push"}'
            else
              echo "No collaborator passed in API call, skipping"
            fi
            
workflows:
  generate-repo:
    when: << pipeline.parameters.api-call >>
    jobs:
      - generate-repo:
          context:
            - repo-create

```

With the above, you may need to make some adjustments. First will be to set the proper GitHub user information, so modify the following lines appropriately:

```auto
git config --global user.email "test@example.com"
git config --global user.name "nick bialostosky"

```

In addition, I am using a context (as mentioned previously) to store the variables. If you are using project-level variables you can remove:

```auto
context:
  - repo-create

```

Otherwise, rename the context to the context where you are storing your variables.

🎉 You should now be setup correctly, the above will only build and kick off repoistories when sending an API call, so to test:

```auto
curl --location --request POST 'https://circleci.com/api/v2/project/github/<org>/<project>/pipeline' \
--header 'Content-Type: application/json' \
-u '<PERSONAL_API_KEY>:' \
--data-raw '{
  "branch": "main",
    "parameters": {
      "api-call": true,
      "collaborator": "username-here",
      "repo-name": "this-should-work"
  }
}'

```

(The above API call will need to be updated to have your project, organization, and personal API token)

### Additional uses

While the above is fairly straightforward, you can expand upon the idea:

1. Have multiple `config.yml` stored at the root and use a pipeline parameter to specify which one to add and commit to the new repo
2. Since the repo creation is triggered via the API, you can actually leverage the API call in other automations or CircleCI builds

### Resources

Here is an example project setup following the above steps:

> **[nbialostosky/create-repo-demo](https://github.com/nbialostosky/create-repo-demo)**
>
> Contribute to nbialostosky/create-repo-demo development by creating an account on GitHub.

Here is one of the repositories created by sending an API call to the above project:

> **[nbialostosky/this-should-work](https://github.com/nbialostosky/this-should-work)**
>
> Contribute to nbialostosky/this-should-work development by creating an account on GitHub.
