Introduce `dev.cdeventsx.scm-branch.initialCommit` as an Experimental CDEvent for DORA
To support DORA’s Lead Time for Change (LTC) metric, we need to track the first project commit on a repository branch. This should be distinguished from branch.created as not all workflows involve code changes be included when creating a branch and it should allow multiple projects be started on the same branch. LTC is developer focused and should be computed from the first code commit.
Since CDEvents lacks a change.committed event, we propose branch.initialCommit as an experimental event under CDEventsX to capture the first project commit in a branch. It is important to denote that the intent is for the developer to signal the start on a project (feature, fix, enhancement, etc.) that should be tracked for the LTC metric.
Proposed Event Definition:
Event Type:
dev.cdeventsx.scm-branch.initialCommit.0.4.1
{
"context": {
"version": "0.4.1",
"id": "<UUID>",
"source": "<SCM URL>",
"type": "dev.cdeventsx.scm-branch.initialCommit.0.4.1",
"timestamp": "<ISO8601>",
"schemaUri": "https://cdeventsx.dev/schema/scm-branch-initialCommit.json",
"chainId": "<Ticket-ID or Commit SHA>"
},
"subject": {
"id": "<Commit SHA>",
"source": "<SCM URL>",
"type": "branch",
"content": {
"repository": "<Repo URL>",
"branch": "<Branch Name>",
"commitSha": "<Commit SHA>",
"author": "<Author Name>",
"message": "<Commit Message>"
}
},
"customData": {
"deployer": "SCM Hook"
},
"customDataContentType": "application/json"
}
Use Case:
DORA requires measuring LTC from the first commit to deployment.
-
branch.initialCommitensures the starting point compatible with LTC tracking. - This enables event correlation between commits, pipelines, and deployments.
Impact:
- Provides an immediate experimental CDEvents solution for tracking LTC.
-
Developers can emit
branch.initialCommitwith apost-commithook. - Allows SCM tools (GitHub, GitLab, Bitbucket) to emit
branch.initialCommitvia apost-receivehook orpushevent.
I have questions related to the implementation of the use cases (maybe you do not have the answer yet):
- How do SCM tools or local
post-commithooks make the difference between aninitialCommitand a non initial? (in an automatic way) - What about the
main/master/trunk/default branches (or other long-lived branches used by gitflow)? No event on those branches? - I'm guessing this approach could not be automated for teams using
commit to master(with feature flags) without branches. - How do you imagine defining the correlation between
branch.initialCommitand following events untilservice.deployedas - those events can be triggered by different applications (several in the chain)
- multiple
initalCommitcan be included into an artifact that will be deployed as a service (+ the case where several artifacts can be packaged together to build the deployed artifact). IHMOchainIddoesn't work for DAG, and I don't know how it could be known by the different tools & translators that produce cdevent.
To be honest, those are the questions I have asked myself since, sometimes, to be able to compute metrics related to several stages (DORA) and also the lifecycle graph.
From 04/01/2025 implementation SIG
Answering above questions:
- How is this event emitted?
- pre|post-commit hooks
- Having metadata inside of the commit message
```
feature: Add new API /hello
---
cdevents:
event-type: initialCommit
```
Can also utilize git notes to add metadata
Add a special git command, /usr/local/bin/git-cdevent, git cdevent <>
Issues with git notes and git commands is high level tools may be problematic
- Who sends the events?
- User could send the event, but not a good approach due to authentication/authorization
- Leaning more towards the SCM service or some webhook adapter that is integrated with the service
Hey @davidB — I really appreciate the depth of your questions. You're thinking about the edge cases and long-term challenges that have been on my mind as well. Let me walk through each one based on my thinking and what we were doing within the Interoperability SIG, some early thought prototypes, and the reasoning behind proposing branch.initialCommit as an experimental event.
- How do SCM tools or local post-commit hooks make the difference between an initialCommit and a non-initial? (in an automatic way)
You're absolutely right; SCM tools don’t natively detect an “initial” commit in a semantic sense. What I am proposing is a convention: developers include a structured commit message that signals intent to start a measurable unit of work.
For example: MYTICKET-1234 Initial Commit: Implement login page
A local post-commit hook or a server-side post-receive hook watches for that message pattern and emits a branch.initialCommit CDEvent. It’s an opt-in mechanism meant to give teams a way to declare the beginning of a feature, project, or change unit they care about tracking.
- What about the main/master/trunk/default branches (or other long-lived branches used by gitflow)? No event on those branches?
Exactly! I chose branch.initialCommit over something like branch.created. The goal is to track when meaningful work begins, not when a branch is created (which might be a UI click in a web tool with no commits). While this is often on short-lived branches tied to tickets, teams using long-lived branches for hotfixes, projects, or epics can still emit a branch.initialCommit event; they just use the structured message to trigger it.
I went through a lot of iteration on naming (e.g., branch.initialProjectCommit), but it opens semantic rabbit holes: is it a project? a feature? a hotfix? Ultimately, the event simply marks “Start counting for X”, where X is whatever identifier the developer chooses to include. (MYTICKET-1234, etc.)
- I'm guessing this approach could not be automated for teams using commit to master (with feature flags) without branches.
There’s no reason it can’t be. Because this isn’t about branching strategy—it’s about log message semantics. If your team commits directly to main, and the developer uses a pattern like: MYTICKET-5678 Initial Commit: Add dark mode toggle then the hook can emit the branch.initialCommit just the same.
The event doesn’t require a short-lived feature branch—it just requires a recognizable signal of developer intent. That becomes the “start” for "Lead Time for Change".
- How do you imagine defining the correlation between branch.initialCommit and following events until
service.deployedas - those events can be triggered by different applications (several in the chain)
Great question. Technically, based on my example, there need not be any other relationship than the ticket closing; other identifiers might require other considerations. We are only trying to mark the start and completion. DORA doesn't care what steps were in between; it cares about how long all of the steps take, regardless of the route. This is how they can compare patterns effectively. Teams that deploy more frequently tend to have smaller deployments. That correlation has nothing to do with the steps.
As a tool builder, I find it a bit disorientating. Lead Time for Change is a time measurement, not a step measurement. As a tool builder, I want to build efficient tools, so the steps matter to me.
- multiple initialCommit can be included into an artifact that will be deployed as a service (+ the case where several artifacts can be packaged together to build the deployed artifact). IHMO chainId doesn't work for DAG, and I don't know how it could be known by the different tools & translators that produce cdevent.
Yes, you are correct. This is a process measurement, not a tool step measurement. If you have an "epic" made up of sub-projects, its branch.initalCommit should occur before any sub-projects and not conclude until they are all successfully deployed, if that is what you choose to measure. For DORA, the artifact that sits in an artifact repository for six months before it goes to production represents six months with no change to production from where the project started or (considering that this is surveyed) are the respondents coloring the response because in their minds it is done.
That's why we, the CDF, are doing this. To move from the subjective measurement to an objective one to prove the correlations.
We’re okay with the idea that this isn’t perfect. But it’s measurable, useful, and interoperable—which makes it a good experimental candidate.
To be honest, those are the questions I have asked myself since, sometimes, to be able to compute metrics related to several stages (DORA) and also the lifecycle graph.
Yes. Exactly. That’s the same direction I am heading. The current proposal is part of a broader blog series (starting here: https://cd.foundation/blog/2025/03/31/getting-started-cdevents-part1) that aims to make DORA metrics observable and computable from events across tools. This represents the start and must be applicable in the basic use cases and the most complex.
I am not aiming for perfection; I am aiming for a good start. We will arrive at the best solution together from good questions like this and good conversation. I am trying to help teams start measuring what matters and feed those learnings into CDEvents and the broader ecosystem.
Thanks again for the thoughtful response. I’d love to hear more about the lifecycle graph work you’ve been exploring—it feels like we’re thinking in the same direction
Thanks for the detailed answer.
Why not extend the subject ticket (with predicate initialCommit or started)?
As
- The beginning (this event) and the end (when the ticket is closed in your example) of the described workflow seem to be related to a ticket
- The event doesn't seem linked to a branch
- Often ticketing systems provide integration with SCM, so all commits (pushed) are detected, and the event could be raised from this system.
- Some ticketing systems provide a workflow with a "start action" used by the developers to notify exactly that (I know some teams using automation: the "first commit" => change state to "started")
Also, sending the event from the dev desktop (local git-hook) introduces security constraints (receiver, collector, hub,... require authn/authz, and allowing local dev = increasing work/maintenance)