-
Notifications
You must be signed in to change notification settings - Fork 70
Cycle time
An important concept for writing programs is cycle time. This is how long it takes from having an idea until users see benefits. There are other definitions that break up this general concept into specific portions of development.
Each project should develop their own notion of cycle time(s)! This is a great discussion with others on "ways of working":
- What do we measure during development?
- Who is interested in improving these measurements?
- Who benefits from going faster?
- Do benefits depend on particular kinds of work? (documentation, deployments, new features, managing projects, etc)
- Are folks on project happy? Do they like the pace of improving the project? (No one finds slow work fun. I wanted to say "slow work is unfun", but maybe it should be anti-fun, the enemy of enjoying your work.)
For this project, I'm focused on: How long from when programmers start work until it is ready to deploy from CI. So discussion is not about:
- Time from forming a new idea until turning it into work you can start
- Time from a deployable CI build until when users see your changes
- Time for management to track different kinds of work
This is my focus because I am focused on your build pipeline. You should have awesome build pipelines that make you happy! The above "not" list is important, and worth your effort, but not what I'm writing about.
Here might be a picture of Cycle Time end-to-end (these are duplicated in What is a build pipeline):
flowchart TB
idea("Idea for improvement")
card("Turn idea into potential work")
analysis("Flesh out work needed")
process("Discussion and moving work to "ready"")
dev("Programmers pick up ready work")
progress("Programmers turn work into feature")
push("Feature goes to the CI pipeline")
ci("CI pipeline builds work")
ready("Feature ready to deploy")
deploy("Feature goes into production")
users("Use software")
subgraph idea_steps [Idea]
idea-->card
card-->analysis
analysis-->process
end
subgraph work_steps [Work]
process-->dev
dev-->progress
progress-->push
push-->ci
ci-->ready
ready-->deploy
end
style work_steps stroke:black,stroke-width:4px
work_steps-->|New ideas|idea_steps
subgraph deploy_steps [Users]
deploy-->|Feature|users
users-->|Start again|idea
end
deploy_steps-->|New ideas|idea_steps
And here is a more focused picture:
flowchart TB
red("RED:<br>Work on programming")
green("GREEN:<br>Local tests pass (unit, et al)")
refactor("REFACTOR:<br>Improve and clean up code")
coverage("Local coverage passes")
local_checks("Local checks pass")
push("Push to shared CI")
pushed("New changes in CI")
ci("Run full build")
ci_checks("Same checks as local + CI-specific checks")
ready("Result ready to deploy")
subgraph work_steps [Write some code]
refactor-->red
green-->refactor
red-->green
end
work_steps-->push_steps
subgraph push_steps [Prepare Git push]
coverage-->local_checks
local_checks-->push
end
push_steps-->ci_steps
subgraph ci_steps [CI]
pushed-->ci
ci-->ci_checks
ci_checks-->ready
end
The key tools for improving cycle time are measure and decide. Yes, that is all! With such generic advice, maybe examples would help.
Everything works as expected:
- Developers are happy with local build times.
- CI completes quick enough to meet everyone's expectations.
- Project quality and security are solid.
This really is the happy path, and what you strive for. And ... there is nothing to change. Your project is in a sweet spot, so be happy. However, keep measuring: you want to stay in this place, and tracking is minimal effort so worth it to stay on top of things.
Let's say you are most interested locally in the red-green-refactor cycle as you write unit tests and passing code, and want to wait until time to push for a full local build with style checks and static analysis. You can do this!
# Run only tests, no other tools to check your code.
# Wait until "push" time for a full build including all checks
$ ./gradlew test
# OR
$ ./mvnw test
Then after you are happy with the tests and code, you can look for other concerns before sharing work with others:
$ ./gradlew clean build
# OR
$ ./mvnw clean verify
# THEN if all is green
$ git push # Your commits
Note that the CI builds call "Earthly" as a CI container for your builds. This is a containerized build that you can also run locally.
You can take advantage of the the "ignores" feature in your CI configuration. This project has both Gradle and Maven builds, and we don't want to, for example, run the Gradle build when only Maven-specific files change, and vice versa.
The example project uses
.github/workflows/ci-earthly-gradle.yml
for the Gradle CI build, and
.github/workflows/ci-earthly-maven.yml
for the Maven CI build,
TODO: Placeholder section
See the code repo for working examples.
This work is dedicated/deeded to the public following laws in jurisdictions
for such purpose.
The principal authors are:
You can always use the "Pages" UI control above this sidebar ☝ to navigate around all pages alphabetically (even pages not in this sidebar), to navigate the outline for each page, or for a search box.
Here is the suggested reading order: