New Project Repo Provisioning
On new Project record in Dataverse, spins up a GitHub repo from a standard template, adds the project owner as collaborator, writes the repo URL back to Dataverse, and emails the owner a welcome kit.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
When a new row is added to the custom Dataverse flowlibs_project table, this flow provisions a matching GitHub repository from a standard project template, adds the named project owner as a push-permission collaborator, writes the new repo URL back onto the originating Dataverse record, and emails the owner a styled welcome kit. End-to-end, a new project goes from "row inserted" to "repo created, collaborator invited, CRM updated, owner notified" in a single event-driven run with no manual GitHub clicks.
Use Case
Platform and engineering teams want a single "new project" entry point in Power Apps or Dataverse that bootstraps the entire GitHub project scaffold — template repo, collaborator invite, CRM-side traceability, and owner onboarding — without anyone clicking through the GitHub UI. This flow is that entry point: one Dataverse insert kicks off the whole sequence.
The flow is ideal for teams that:
- Event-driven via Dataverse SubscribeWebhookTrigger — no polling lag
- One Dataverse insert provisions repo, collaborator, CRM writeback, and welcome email
- Repo created from a standard template, so every project starts with the same scaffolding
- Collaborator invite uses raw PUT /collaborators so existing PAT works without an extra OAuth scope
- Writeback step uses runAfter: [Succeeded, Failed] so a missing GitHub login doesn't lose the repo URL on the Project record
- Slug-ifies the project name into a clean repo name automatically
Flow Architecture
When a row is added (`flowlibs_project`)
TriggerDataverse `SubscribeWebhookTrigger`, `subscriptionRequest/message: 1` (Create), `scope: 4` (Organization). `runas` intentionally omitted.
Initialize 11 variables
InitializeVariableCaptures env vars + trigger body fields: `varRepoOwnerOrg`, `varTemplateOwner`, `varTemplateRepository`, `varDefaultPrivate` (boolean), `varGitHubPAT`, `varProjectId`, `varProjectName`, `varProjectDescription`, `varOwnerEmail`, `varOwnerGitHubLogin`, `varRepoName` (slug-ified).
Create_Repository_From_Template
OpenApiConnection (GitHub)`CreateRepositoryUsingTemplate` with `templateOwner`, `templateRepository`, `body/owner`, `body/name`, `body/description`, `body/private` from the variables.
Init `varNewRepoUrl`
InitializeVariableCaptures `outputs('Create_Repository_From_Template')?['body/html_url']` for reuse.
Add_Project_Owner_As_Collaborator
Http`PUT /repos/{owner}/{repo}/collaborators/{login}` with Bearer PAT, body `{ permission: 'push' }`.
Update_Project_Row_With_Repo_URL
OpenApiConnection (Dataverse)`UpdateRecord` on `flowlibs_projects` writing `flowlibs_reponame` and `flowlibs_repositoryurl`. `runAfter: [Succeeded, Failed]` so collaborator failures don't lose the writeback.
Send_Welcome_Kit_Email
OpenApiConnection (Outlook)`SendEmailV2` with HTML body containing repo URL, template path, collaborator confirmation, and onboarding checklist. Subject: `Your new project repository is ready: {projectName}`.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GitHubOwner | String | your-org | GitHub org or user under which new repos are created. |
| flowlibs_NewProjectTemplateOwner | String | your-org | GitHub org or user that owns the template repo. |
| flowlibs_NewProjectTemplateRepository | String | project-template | Template repository slug used as the basis for each new project repo. |
| flowlibs_NewProjectDefaultPrivate | String | true | Whether new repos default to private. String-as-boolean: `true` or `false`. |
| flowlibs_GitHubPAT | Secret | <configure> | Personal Access Token (with `repo` scope) used as Bearer credential for the raw HTTP collaborator-invite step. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Microsoft Dataverse | shared_commondataserviceforapps | SubscribeWebhookTrigger (trigger on `flowlibs_project` (Create, Organization scope)) UpdateRecord (writeback to the originating Project row) |
| GitHub | shared_github | CreateRepositoryUsingTemplate (provisions the new repo from the template) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (sends the welcome kit to the project owner) |
| HTTP (built-in) | shared_http | PUT /repos/{owner}/{repo}/collaborators/{login} (invites the owner with `push` permission via Bearer PAT) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Deploying to another environment
- Confirm the flowlibs_project Dataverse table exists in the target environment with columns flowlibs_name, flowlibs_description, flowlibs_owneremail, flowlibs_ownergithublogin, flowlibs_reponame, flowlibs_repositoryurl (create it if missing — the solution does not ship the table). Import the solution, then set flowlibs_GitHubOwner, flowlibs_NewProjectTemplateOwner, flowlibs_NewProjectTemplateRepository, flowlibs_NewProjectDefaultPrivate, and flowlibs_GitHubPAT (PAT with repo scope). Bind Dataverse, GitHub, and Outlook connection references, re-select the flowlibs_project table on the trigger so Dataverse binds the webhook to live metadata, then turn the flow on.
- Drop the PAT dependency
- Replace the HTTP PUT /collaborators step with the GitHub connector's AddCollaborator action and remove the flowlibs_GitHubPAT env var. Eliminates the need to manage a Personal Access Token.
- Approval gate before creation
- Insert StartAndWaitForApproval after the variable-init chain and gate Create_Repository_From_Template on the Approve branch so a human signs off before a repo is provisioned.
- Default branch protection + topics
- Add HTTP calls after the create step hitting PUT /repos/{owner}/{repo}/topics
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Slug-ified repo name
Converts the human-readable project name into a clean lowercase, hyphenated GitHub repo slug.
EXPR.02Default-private boolean coercion
Coerces the String env var into a real boolean before passing to GitHub's `body/private` field.
EXPR.03Capture new repo URL
Reads the freshly created repo's HTML URL from the GitHub action output for reuse downstream.
EXPR.04Build collaborator-invite URL
Assembles the full GitHub REST URL for the `PUT /collaborators/{login}` HTTP step.
EXPR.05Null-safe trigger field read
Falls back to an empty string when the optional description column is null.
EXPR.06Read GitHub PAT env var
Reads the Secret env var that holds the GitHub Personal Access Token used as a Bearer credential.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.