To thoroughly analyze and discuss non-trivial decisions or features, we rely on collaborative document editing, taking several iterations of proposals and feedbacks before the actual planning and implementation.
Macro changes that impact the software and system architecture such as logging, authentication, integration between components and 3rd party systems, format and structure of data etc. must be initially outlined in a document (RFC) that is shared and discussed with the rest of the team. RFCs are also useful for describing high-level activities not necessarily related to software development - for example: topics related to the legal aspects of the project or the interaction with public subjects.
For hystorical reasons old RFCs are called CDMs (Cittadinanza Digitale Memos) and are stored in a publicly accessible folder named CDM in the Digital Team Google Drive.
All team members are invited to write new RFCs and comment the existing ones.
New RFC documents must be named IO-RFC-{n} - {title}
where n
is an incremental
number (one plus the highest memo in the RFC folder) and title
is a short title
describing the proposal (when in doubt try to be consistent with the current RFCs
or ask advice in the #dev_io
channel).
When writing an RFC, assume that the reader knows almost nothing about the context, the issues and the reasons that motivate any eventual implementation proposal.
We currently write RFCs in the Italian language (but if you feel like writing in English, you are welcome to do so).
The RFC should be roughly structured as following:
- A title (same as the name of the document)
- Author
- Current state of the document (i.e. work in progress, waiting for review, planned, implemented)
- A Context (Contesto) section where we explain why the document has been written (i.e. the starting point, the need, the current state of things)
- A Proposal (Proposta) section where we explain what the RFC is proposing to implement or change, how this proposal solves a certain need or problem and (if applicable) what are the effects on other systems.
Once the first draft has been completed, the author shares the document with the
team in the #dev_io
Slack channel, asking for feedback and/or tagging
some key stakeholder (ie. the CTO) using Google Docs comments feature.
There may be several iterations of feedbacks/comments and updates.
Once a RFC is finalized and approved for implementation, it must be translated into development stories that get added to the backlog of each affected component.
For registering architectural decisions we rely on Architecture Decision Records (ADR):
See the ADRs repository.
- Always create a story for things you work on. If it is worth spending time on, it is worth creating a story since that enables other people to learn and help. You can always edit the description or close it when the problem changed to something different or was solved. (TODO: link to Pivotal projects)
- Always start with the "why" not with the "how": not every solution will solve the problem at hand. Keep discussions focused by defining the problem first. Also, don't rush to the first solution it comes to mind, unless the solution is obvious, try to propose multiple options and ask advice from business and product team-mates if needed.
- Double link stories with related conversations. E.g. if there’s an Instabug ticket that causes you to open a story on Pivotal Tracker, make sure to document the story link in the Instabug issue and vice versa. The same states for notable slack conversations.
- If two stories are related, crosslink them (a link from each story to the other one). When a story blocks another story, use the blockers feature of Pivotal Tracker.
- After a discussion about a feature update the story description with the consensus or final conclusions. This makes it much easier to see the current state of a story for everyone involved in the implementation and prevents confusion and discussion later on.
- Submit the smallest item of work that makes sense. When creating a story describe the smallest fix possible, put suggestions for enhancements in separate stories and link them.
- Do not leave stories open for a long time, stories should be actionable and realistic. If you are assigned to a story but don't have time to work on it, assign it to someone else or move it to the icebox. Consider removing idle stories from the "Started" state to not compromise velocity auto-computation.
- Make a conscious effort to prioritize your work. The priority of items depends on multiple factors: Is someone waiting for the answer? What is the impact if you delay it? How many people does it affect, etc.? This is detailed in Engineering Workflow. (TODO: link to engineering workflow)
- Pick stories from the top of the backlog.
- Assign a story to yourself as soon as you start to work on it, but not before that time. If you complete part of a story and need someone else to take the next step, re-assign the story to that person.
- When re-assigning a story, make sure that the story description contains the latest information. The story description should be the single source of truth.
- Do not Accept stories about changes not yet deployed into production. Do not close a story until it is really done.
- When closing a "wont-fix" story (use the label!) leave a comment explaining why you are closing it.
- features: stories that provide verifiable value to the user. They have a story point estimate. Use the form
As <type of user> I want to <some goal> so that <some reason>
for features stories. - chores: stories that are necessary but provide no direct, obvious value to the user. They don’t require extra validation when they’re finished, so the states for chores are just unstarted, started, and accepted.
- bugs: unintended behavior that can be related to features. Bugs have the same states as features.
- releases: milestone markers that allow your team to track progress toward concrete goals. Releases only have unstarted and accepted states.
Titles / descriptions must be:
- Understandable the story or its related description must provide all the necessary information in order to be understood by everyone working on the project with minimal information about the context
- Friendly put implementation details into the story description
Stories must be:
- Independent (can be built separately to other stories)
- Negotiable (requirements can be adapted)
- Valuable (provides benefit to the end-user)
- Estimable (to reasonable accuracy)
- Small (can be built within one iteration)
- Testable (can be verified by QA)
see https://medium.com/tribalscale/writing-technical-user-stories-434bf96f1dd5
Bad: Implement login screen
Good: As an Author I want to be able to login in order to start edit the content
Bad: Create a modal to show errors
Good: As an Editor I want to be notified in case some error occurs in order to plan a retry
...
Features and bugs have the following states:
- Unscheduled: this are stories in the Icebox, there's no plan to fix them soon.
- Unstarted: development on this story hasn't started yet.
- Started: development has started.
- Finished: the relative Pull Request is merged into master.
- Delivered: Pull Request is deployed into production.
- Accepted: the fix has solved the issue, the story is closed.
- Rejected: doesn't meet the acceptance criteria according to the user or product owner, a new fix is needed.
- 0 points – it's super simple and I'm sure I can do it in minutes.
- 1 point – I already know how to complete this story. It looks easy and it should be quick
- 2 points – I'm not sure. There might be something I don't know how to do and/or unforeseen events
- 3 points – it's complex and I need to figure out what to do.
- Start the related story.
- Create a new feature branch, the name should be meaningful, e.g:
12345-fix-payment-button
where12345
is the Pivotal story ID. - Make your changes in the branch and commit using descriptive messages (see below for guidelines on commit messages). Prepend the commit message with the Story # you're working on. Example:
[#12345] Fixes payment button
. - Push the branch:
git push -u origin 12345-fix-payment-button
. - Create a pull request from your branch.
- Prepend the pull request title with the Story #. Examples:
[#12345] Fixes payment button
. - If the Pull Request is still a work in progress, create a draft pull request.
- Add at least one human reviewer to your story.
- Attach the Pull Request to the story by clicking on the Attach from Github link in the story page and pasting the PR URL.
- Press Finish on the story on Pivotal Tracker.
- Wait for at least one of the human reviewer to review the change.
- Update the master branch within your local repository with
git checkout master
andgit pull
. If you have other branches that need to be updated, then run also:git checkout other-branch
andgit pull --rebase . master
. Note that subsequent pushes for these branches will require a-f
since history has been rewritten by rebasing. - Create a new relase of the packages using
yarn release-it <patch|minor|major>
- Deploy, or wait for someone to deploy the newly written code.
- Once deployed press
Deliver
on the story on Pivotal Tracker. - Based on how it goes the story will be accepted or rejected.
- Every developer should spend from 30min to 1h each day on code reviews.
- Each PR should be as small as possible: the general guideline is to create pull requests ranging from 200 to 400 lines of code, not more.
- Include explanation comments in the PR: this can help the reviewers in making the review faster. At the same time try to be succinct, not verbose, comments should have a high informational density.
- Ask for feedback early by creating draft pull requests. This can shorten dramatically approval and review time.
When you need to create a new project repository, use a repository template. Here are the available templates:
- io-template-typescript: For nodejs/Typescript projects