GitHub Actions - Create GitHub repository

Sample Self-Serve Action to create a new GitHub repository.

This Self-Serve Action allows you to centralize repository creation in configure8 using a golden path that codify your standards. We are also creating a service inside configure8 Universal Catalog via our API, keeping all new projects visible and organized.

Create configure8 API key

We will use the configure8 public API to create a service in the Catalog once the repository is created.

If you don't have a configure8 API Key, follow this guide to create a new one.

Action setup

1. Details

Go to your configure8 app into the Self Service menu. Select "+ Add Action" button.

Fill in your action Name, Type, Logo, Status and Description.

2. Context

Set your action Owners, Visibility Control, Viewers, Allowed People and Applies to fields.

3. User Input

Activate the user input toggle so that you can insert the JSON for user input.

Paste the JSON below to visualize the inputs we are asking to the user in this sample.

[
  {
    "required": true,
    "type": "text",
    "title": "Repository name",
    "payloadName": "repoName",
    "helpText": "Provide unique name for repository"
  },
  {
    "type": "text",
    "title": "Repository description",
    "payloadName": "repoDescr",
    "helpText": "Provide repository description"
  },
  {
    "type": "checkbox",
    "title": "Create private repository?",
    "payloadName": "private",
    "defaultValue": "true",
    "helpText": "Turn On if new repository should be private"
  },
  {
    "type": "checkbox",
    "title": "Create README?",
    "payloadName": "autoInit",
    "defaultValue": "true",
    "helpText": "Turn On if new repository should contain README"
  },
  {
    "type": "dropdown",
    "title": "Project type",
    "payloadName": "type",
    "defaultValue": "POC",
    "options": [
      {
        "value": "POC",
        "label": "POC"
      },
      {
        "value": "MVP",
        "label": "MVP"
      },
      {
        "value": "Internal",
        "label": "Internal"
      },
      {
        "value": "White label",
        "label": "White label"
      }
    ]
  }
]

4. Method

Set the following values:

Webhook URL:

https://api.github.com/repos/YOUR_USER/YOUR_REPO/actions/workflows/ssa-run-create-user-repository.yml/dispatches

Change the USER and REPO above to reflect your GitHub account. The workflow name (ssa-run-create-user-repository.yml) should be the same created in below section Backend setup - create workflow.

Headers:

{
  "Authorization": "token ghp_YOUR_GITHUB_TOKEN",
  "Accept": "application/vnd.github.v3+json"
}

Payload:

{
  "ref": "main",
  "inputs": {
    "c8-report-token": "{{ c8ReportToken }}",
    "reportUrl": "https://app.configure8.io/self-service/api/v1/reports/webhook",
    "gitHubToken": "token ghp_YOUR_GITHUB_TOKEN",
    "orgApiKey": "c8ak_YOUR_C8_API_KEY",
    "repoName": "{{ repoName }}",
    "repoDescr": "{{ repoDescr }}",
    "private": "{{ private }}",
    "autoInit": "{{ autoInit }}",
    "lifecycle": "{{ type }}"
  }
}

Backend setup

Create a Github token

Go to your GitHub account and create a personal access token.

Create a repository or use a existing one

Create or use a repository that matches the YOUR_REPO name passed on the webhook URL.

Create a workflow to execute the action

Inside YOUR_REPO, create a new workflow with the same name we used in the Webhook URL, in this case 'ssa-run-create-user-repository.yml' with the following content:

name: 'SSA Create User Repository Workflow'

on:
  workflow_dispatch:
    inputs:
      c8-report-token:
        description: Report token
        required: true
      reportUrl:
        description: SSA Report URL
        required: true
      orgApiKey:
        description: Token public org
        required: true       
      gitHubToken:
        description: GIT Token
        required: true       
      repoName: 
        description: 'Name of the repository to be created'
        required: true
        default: ''
      lifecycle: 
        description: 'Lifecycle type'
        required: false
        default: ''
      repoDescr: 
        description: 'Description of the repository to be created'
        required: false
        default: ''
      private: 
        description: 'private repository'
        required: false
        default: false
      autoInit: 
        description: 'Create README file'
        required: false
        default: false


jobs:
  create_repo_job_user_token:
    runs-on: ubuntu-latest
    permissions: write-all
    steps:
      - name: Print parameters
        run: |
          echo "Token: ${{ github.event.inputs.c8-report-token }}"
          echo "Report URL: ${{ github.event.inputs.reportUrl }}"
          echo "Repository name: ${{ github.event.inputs.repoName }}"

      - name: Set startedAt
        id: set_startedAt
        run: |
          echo "::set-output name=startedAt::$(node -e 'console.log(new Date().toISOString())')"

      - name: Set default status
        id: status
        run: |
          echo "::set-output name=status::complete"

      - name: Use Node.js
        uses: actions/setup-node@v2

      - name: Creating GitHub User Repository
        id: create-repo
        run: |
          repoName="${{ github.event.inputs.repoName }}"
          orgAdminToken="${{ github.event.inputs.gitHubToken }}"
          autoInit="${{ github.event.inputs.autoInit }}" 
          private="${{ github.event.inputs.private }}" 
          repoDescr="${{ github.event.inputs.repoDescr }}" 

          response=$(curl -X POST -H "Authorization: $orgAdminToken" \
            -H "Accept: application/vnd.github+json" \
            -H "X-OAuth-Scopes: repo" \
            -d '{
              "name": "'"$repoName"'",
              "description": "'"$repoDescr"'",
              "private": '"$private"',
              "auto_init": '"$autoInit"'
            }' \
            "https://api.github.com/user/repos")

          echo "API Response: $response"

          repoId=$(echo "$response" | jq -r '.id')
          repoFullName=$(echo "$response" | jq -r '.full_name')
          repoUrl=$(echo "$response" | jq -r '.html_url')

          if [[ -n "$repoUrl" ]]; then
            echo "::set-output name=repo-url::$repoUrl"
          else
            echo "::error::Failed to create repository"
            echo "::set-output name=status::failed"
          fi

          if [[ -n "$repoId" ]]; then
            echo "::set-output name=repo-id::$repoId"
          else
            echo "::error::Failed to create repository"
            echo "::set-output name=status::failed"
          fi

          if [[ -n "$repoFullName" ]]; then
            echo "::set-output name=repo-full-name::$repoFullName"
          else
            echo "::error::Failed to retrieve repository full name"
            echo "::set-output name=status::failed"
          fi

      - name: Log URL to the repo
        run: 
          echo "The new repo is ${{ steps.create-repo.outputs.repo-url }}"
          echo "The new repo is $repoUrl"

      - name: Send POST request to create repo
        id: create-c8-repo
        run: |
          API_KEY="${{ github.event.inputs.orgApiKey }}"
          NAME="${{ github.event.inputs.repoName }}"
          DESCRIPTION="${{ github.event.inputs.repoDescr }}" 
          URL="${{ steps.create-repo.outputs.repo-url }}"
          PROVIDER="GitHub"
          PROVIDER_RESOURCE_KEY="${{ steps.create-repo.outputs.repo-id }}"
          PROVIDER_ACCOUNT_ID="${{ github.actor }}"
          LOCATION="${{ steps.create-repo.outputs.repo-full-name }}"

          request_body='{
            "name": "'"$NAME"'",
            "description": "'"$DESCRIPTION"'",
            "url": "'"$URL"'",
            "provider": "'"$PROVIDER"'",
            "providerResourceKey": "'"$PROVIDER_RESOURCE_KEY"'",
            "providerAccountId": "'"$PROVIDER_ACCOUNT_ID"'",
            "location": "'"$LOCATION"'"
          }'

          echo "API Request Body: $request_body"
          response=$(curl -X POST -H "Content-Type: application/json" -H "api-key: $API_KEY" \
            -d "$request_body" \
            https://app.configure8.io/public/v1/catalog/entities/repository)

          echo "API Response Body: $response"

          repositoryId=$(echo "$response" | jq -r '.id')

          if [[ -n "$repositoryId" ]]; then
            echo "::set-output name=repository-id::$repositoryId"
          else
            echo "::error::Failed to create c8 repository"
            echo "::set-output name=status::failed"
          fi
      
      - name: Send POST request to create service
        run: |
          API_KEY="${{ github.event.inputs.orgApiKey }}"
          NAME="${{ github.event.inputs.repoName }}"
          DESCRIPTION="${{ github.event.inputs.repoDescr }}" 
          LIFECYCLE="${{ github.event.inputs.lifecycle }}"
          REPOSITORYID="${{ steps.create-c8-repo.outputs.repository-id }}"

          response=$(curl -X POST -H "Content-Type: application/json" -H "api-key: $API_KEY" \
            -d '{
              "name": "'"$NAME"'",
              "description": "'"$DESCRIPTION"'",
              "repositoryId": "'"$REPOSITORYID"'",
              "lifecycle": "'"$LIFECYCLE"'"
            }' \
            https://app.configure8.io/public/v1/catalog/entities/service)
          
          echo "API Response: $response"
      

      - name: Set completedAt
        id: set_completedAt
        run: |
          echo "::set-output name=completedAt::$(node -e 'console.log(new Date().toISOString())')"

      - name: Send results over HTTP
        run: |
          token="${{ github.event.inputs.c8-report-token }}"
          reportUrl="${{ github.event.inputs.reportUrl }}"
          status="${{ steps.status.outputs.status }}"
          startedAt="${{ steps.set_startedAt.outputs.startedAt }}"
          completedAt="${{ steps.set_completedAt.outputs.completedAt }}"

          # Report SSA result
          if ! curl -X POST \
            -H "c8-report-token: $token" \
            -H "Content-Type: application/json" \
            -d "{\"status\": \"$status\", \"startedAt\": \"$startedAt\", \"completedAt\": \"$completedAt\"}" \
            "$reportUrl"; then
            echo "Failed to send results over HTTP"
            exit 1
          fi

Commit the workflow and done!

Run Action and view results

Onwers and allowed users will be able to execute it and view the results:

Last updated

Copyright © 2023 configure8, Inc. All rights reserved.