Skip to main content

Scaffold a new service

This guide takes 7 minutes to complete, and aims to demonstrate the power of self-service actions in Port.

Prerequisites
  • This guide assumes you have a Port account and that you have finished the onboarding process. We will use the Service blueprint that was created during the onboarding process.
  • You will need a Git repository (GitHub, GitLab, Bitbucket or Azure DevOps) in which you can place a workflow/pipeline that we will use in this guide. If you don't have one, we recommend creating a new repository named Port-actions.

The goal of this guide

In this guide we will create an action that initializes a new Git repository. In reality, such an action can be used by developers to scaffold new services.

After completing it, you will get a sense of how it can benefit different personas in your organization:

  • Developers will be able to scaffold new services easily.
  • R&D managers will be able to get an overview of new services - how many were created and by whom.
  • Platform engineers will be able to control permissions to ensure only the relevant people can create new services.

Setup the action's frontend

  1. Head to the Self-service page of your portal.

  2. Click on the + Action button in the top-right corner:

  3. Fill the basic form with the Title and Description and select Create and Service for the Operation and Blueprint respectively.


  4. Click on the Next to proceed to the User Form tab and click on + Input.

  5. Enter Service name as the Title, select Text for the Type, set Required to True, and click on the Create button.


  6. Click on the Next to configure the Backend.

Define backend type

Now we'll define the backend of the action. Port supports multiple invocation types, depending on the Git provider you are using.

Fill out the form with your values:

  • Replace the Organization and Repository values with your values (this is where the workflow will reside and run).

  • Name the workflow port-create-repo.yml.

  • Fill out your workflow details:


  • Scroll down to the Configure the invocation payload section.
    This is where you can define which data will be sent to your backend each time the action is executed.

    For this example, we will send two details that our backend needs to know - the service name, and the id of the action run.
    Copy the following JSON snippet and paste it in the payload code box:

    {
    "port_context": {
    "runId": "{{ .run.id }}"
    },
    "service_name": "{{ .inputs.service_name }}"
    }

The last step is customizing the action's permissions. For simplicity's sake, we will use the default settings. For more information, see the permissions page. Click Save.

The action's frontend is now ready 🥳


Setup the action's backend

Now we want to write the logic that our action will trigger.

Important

If the GitHub organization which will house your workflow is not the same as the one you'll create the new repository in, install Port's Github app in the other organization as well.

  1. First, let's create the necessary token and secrets:
  • Go to your GitHub tokens page, create a personal access token (classic) with repo, admin:repo_hook and admin:org scope, and copy it (this token is needed to create a repo from our workflow).

SAML SSO

If your organization uses SAML SSO, you will need to authorize your token. Follow these instructions and then continue this guide.

  • Go to your Port application, click on the ... in the top right corner, then click Credentials. Copy your Client ID and Client secret.
  1. In the repository where your workflow will reside, create 3 new secrets under Settings->Secrets and variables->Actions:
  • ORG_ADMIN_TOKEN - the personal access token you created in the previous step.
  • PORT_CLIENT_ID - the client ID you copied from your Port app.
  • PORT_CLIENT_SECRET - the client secret you copied from your Port app.


  1. Now let's create the workflow file that contains our logic.
    First, ensure that you have a .github/workflows directory, then create a new file named port-create-repo.yml and use the following snippet as its content (remember to change <YOUR-ORG-NAME> on line 15 to your GitHub organization name):
tip

The GitHub workflow example below assumes that you will use the cookiecutter template specified in line 27.
If you would instead prefer to use a template from a private repository, replace the line in the template below with the following, ensuring to specify the GitHub org and repo name where instructed:
cookiecutterTemplate: https://oauth2:$ORG_ADMIN_TOKEN@github.com/$<GITHUB-ORG-NAME>/$<TEMPLATE-REPO>.git.
If the template GitHub repo is not within the same organization where this repo will be placed, please ensure you replace the ORG_ADMIN_TOKEN parameter with a token containing the same parameters used when you created the token in the previous step.

Github workflow (click to expand)
port-create-repo.yml
name: Scaffold a new service
on:
workflow_dispatch:
inputs:
port_context:
required: true
description: Includes the action's run id
service_name:
required: true
description: The name of the new service
type: string
jobs:
scaffold-service:
env:
ORG_NAME: <YOUR-ORG-NAME>
runs-on: ubuntu-latest
steps:
- uses: port-labs/cookiecutter-gha@v1.1.1
id: scaff
with:
portClientId: ${{ secrets.PORT_CLIENT_ID }}
portClientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
token: ${{ secrets.ORG_ADMIN_TOKEN }}
portRunId: ${{ fromJson(inputs.port_context).runId }}
repositoryName: ${{ inputs.service_name }}
portUserInputs: '{"cookiecutter_app_name": "${{ inputs.service_name }}" }'
cookiecutterTemplate: https://github.com/lacion/cookiecutter-golang
blueprintIdentifier: "service"
organizationName: ${{ env.ORG_NAME }}
tip

This workflow uses Port's cookiecutter Github action to scaffold the new repository.

Cookiecutter template

The cookiecutter templates provided in the workflows are just examples, you can replace them with any other cookiecutter template you want to use, by changing the value of the relevant template variable in the workflow.

All done! The action is ready to be used 🚀

Execute the action

Head back to the Self-service page of your Port application:

  1. Click on Create to begin executing the action.

  2. Enter a name for your new repository.

    Repository name restrictions

    Some Git providers (for example, GitHub) do not allow spaces in repository names.
    We recommend using underscores or hyphens instead of spaces.

  3. For some of the available Git providers, additional inputs are required when executing the action.

When executing the Bitbucket scaffolder, you will need to provide two additional inputs:

  • Bitbucket Workspace Name - the name of the workspace to create the new repository in.
  • Bitbucket Project Key - the key of the Bitbucket project to create the new repository in.
    • To find the Bitbucket project key, go to https://bitbucket.org/YOUR_BITBUCKET_WORKSPACE/workspace/projects/, find the desired project in the list, and copy the value seen in the Key column in the table.
  1. Click Execute. A small popup will appear, click on View details:


  1. This page provides details about the action run. As you can see, the backend returned Success and the repo was successfully created (this can take a few moments):


Logging action progress

💡 Note the Log stream at the bottom, this can be used to report progress, results and errors. Click here to learn more.

Congratulations! You can now create services easily from Port 💪🏽

Possible daily routine integrations

  • Send a slack message in the R&D channel to let everyone know that a new service was created.
  • Send a weekly/monthly report for managers showing all the new services created in this timeframe and their owners.

Conclusion

Creating a service is not just a periodic task developers undertake, but a vital step that can occur on a monthly basis. However, it's crucial to recognize that this is only a fragment of the broader experience that we're striving to create for developers. Our ultimate goal is to facilitate a seamless transition from ideation to production. In doing so, we aim to eliminate the need for developers to navigate through a plethora of tools, reducing friction and accelerating the time-to-production.
In essence, we're not just building a tool, but sculpting an ecosystem that empowers developers to bring new features to life with utmost efficiency.