đ Table of contents
- Sprint 1
- Sprint assesment
- Sprint Planning
- User stories and tasks
- Scrum backlogs
- GitHub organizations
- GitHub Projects
- đââď¸ Sprint 1 planning
- GitHub issues
- Tips for the teamwork
- The README file
- Daily Scrum
- Git branches
- Developer guide documentation
- JAR
- Deployment
- Separate branch for the production code
- GitHub release
- Sprint Review
Sprint 1
This week weâll start working on the project described by the Product Owner in the project description. As we have learned, in Scrum the project advances in short iterations called Sprints. Each of our three Sprints last two weeks. This week is the start of the Sprint 1.
Starting from this week, you will be working with your team. That means that, you will be working on the exercises together. You also need to work on the exercises outside the weekly sessions. If you donât know your team members, you can find their names on Moodle.
Sprint assesment
All of this Sprintâs exercises are submitted to this Moodle submission. The submission should only contain the link to your teamâs GitHub repository created in exercise 2. Each team member has to submit the GitHub repository link. The submission deadline is on 22.4. at 12:00, so we will be working on the exercises for the next two weeks.
The Sprint assesment is done based on the exercises 1-32. The team can earn up to 15 points from this Sprint. The assesment is done at the end of the Sprint during the Sprint Review event.
Sprint Planning
At the beginning of each Sprint, the Sprint Planning event is organized. During this event the whole Scrum Team participates in planning the requirements for the Sprint. As we have learned, these requirements are commonly documented as user stories, which are a short, simple description of a feature told from the perspective of the person who desires the new feature in the software. These user stories are added to a Product Backlog, which sort of an prioritized todo-list of user stories for the project.
The idea of Sprint Planning is not to make long term plans, for example what project should look like after three months. Because requirements tend to change, we should only do planning for the near future, usually just for the upcoming Sprint. Thatâs why Sprint Planning event commonly only takes at most a few hours.
The Product Ownerâs responsibility during the event is to prioritize the user stories on the Product Backlog so that the Developers know what to focus on during the upcoming Sprint. Developers discuss which of the highest priority user stories they are able to implemented during the upcoming Sprint. The chosen user stories for the Sprint are divided into more technical tasks. These tasks are added to a Sprint Backlog, which sort of an Developersâ todo-list for the Sprint.
User stories and tasks
User story should be described from the perspective of the user and should not contain technical details about the implementation. This way, the non-technical Product Owner and the Developers speak the same language.
Still, the Developers need to make technical planning to know how to actually implement the features described by the user stories. During Sprint Planning event each user story chosen for the Sprint are split into multiple technical tasks. User storyâs tasks are basically technical descriptions of what needs to be done to implement the feature described by the user story. Tasks are just for the Developers, so not even a tiny technical detail should be omitted.
For example, letâs consider the following user story:
As a content creator I want to create a new blog so that I can start writing blog posts.
During Sprint Planning Developers discuss the technical steps required to implement the described feature:
âWeâll need a page with a form that has text fields for the blogâs name and description. Also, there needs to be a button to submit the form.â
â John, one of the Developers
âThatâs right, John. To render the page weâll need a controller class for the backend. The controller class should have a method that renders a Thymeleaf template of the page. Maybe the class name could be for example BlogController. What do you guys think?â
â Mary, one of the Developers
âSounds good to me, Mary. What about the form submission? I think we need a controller method for that as well. We should add a new blog entry to the database based on the submitted name and description. For this we could use the H2 database and Hibernate. We need a JPA entity and JPA repository class class for the blog.
â Jane, one of the Developers
While discussing the technical details, the Developers document a todo-list of tasks with a short description. Developers also consider the order of the tasks:
Add a Blog JPA entity class and a BlogRepository JPA repository class
Add a Thymeleaf template for the blog creation form containing fields for name and description
Add a BlogController controller class and methods for rendering and handling the submission of the blog creation form
These tasks are added to the Sprint Backlog.
Scrum backlogs
The âScrum Artifactsâ section of the Scrum Guide describes the artifacts used in Scrum. Artifacts are information that the Scrum Team and stakeholders use to detail the product being developed, actions to produce it, and the actions performed during the project. These artifacts increase the transparency of the process. Two of the most important artifacts are the Product Backlog and Sprint Backlog.
Product backlog
The Product Backlog is a prioritized list of requirements for the developed software. Commonly these requirements are documented as user stories. On top of new features, Product Backlog items can also be for example bug fixes. The Product Backlog is altered constantly during the Sprints, mostly during the Sprint Planning event. For example, new user stories are added, old ones are edited or their priority is changed.
The Product Ownerâs responsibility is to prioritize the user stories in the Product Backlog, but the whole Scrum Team participates in the definition of the user stories. The Product Owner should also make sure that the user stories implemented during a Sprint match the stakeholderâs requirements. Once a user story is implemented during a Sprint and the implementation is accepted by the Product Owner, the user story can be removed from the Product Backlog.
A good Product Backlog has the DEEP characteristics:
- Detailed appropriately: the high-priority user stories (at the top of the Product Backlog) are described in a more detail than the low-priority user stories. This is because the high-priority user stories are the ones that will be implemented soon, maybe during the upcoming Sprint. That is why it is important that these user stories fulfill the INVEST criteria and are ready for the implementation.
- Estimated: the user stories in the Product Backlog should be estimated. That is, the Developers have considered the efforts required to implement each user story and they have communicated it with the Product Owner. Having a rough estimate for the user stories helps the Product Owner in the priorization.
- Emergent: the Product Backlog evolves constantly: old user stories are completed, new user stories emerge and priorization changes
- Prioritized: all user stories are in a prioritized order in the Product Backlog. The user stories at the top of the Product Backlog are the ones that Product Owner considers to produce most value for the stakeholders.
Product Backlog can be thought as the todo-list of user stories for the project. Like in a todo-list, the user stories are in the order that they should be completed. That is, most important user stories are on the top of the list.
Sprint backlog
During Sprint Planning event, the Developers decide the amount of user stories they manage to implemented during the upcoming Sprint. The selected user stories are chosen from the top (highest priority) of the Product Backlog. The chosen user stories are split into technical tasks. These tasks are added to a Sprint Backlog.
Deciding the amount of user stories for the Sprint can be quite tricky at first. It is hard to estimate the amount of effort it takes to implement a certain user story. But, the estimation gets easier in time.
The Sprint Backlog should represent the work needed to be done during the Sprint and the progress of that work. That is, the following points should be seen from the Sprint Backlog:
- Which user story is each task related to?
- Which team member is assignment to each task, i.e. who is working on the task?
- Whatâs the progress of each task? For example, has somebody started working or the task, or is the task done?
This information is constantly kept up-to-date during the Sprint. For example, if a certain task is completed, it should be seen from the Sprint Backlog.
Sprint Backlog can be thought as the todo-list of tasks for the current Sprint. Each task is commonly related to a certain user story.
Backlog platforms
Sprint Backlog is commonly organized as taskboard that has columns for different progress states. These states can be for example âNot startedâ (nobody has started working on the task), âIn progressâ (somebody is currently working on this task), and âDoneâ (the task is completed). The tasks themselves are cards assigned to one of these states depending on their progress. The tasks are moved from one state to another until they are done.
Taskboards are either physical taskboards, for example whiteboards in an office, or virtual taskboards. These days, it is quite common that a virtual taskboard are used as Product Backlogs and Sprint Backlogs. Jira and GitHub projects are perhaps the most widely used taskboard platforms in the industry. During this course we will be using GitHub projects because it integrates very well with our GitHub workflow. But, before we can start using GitHub projects, we need to create a repository for our project.
GitHub organizations
When a software development teams is working on project together, the project can have multiple repositories and different team members might only have access to certain repositories. To have more control over the repository access, the repositories arenât personal repositories created by certain team member. Instead the repositories belong to certain organization and team members can be invited to join that organization.
Similarly as a repository, an organization can be added on GitHub by cliking the plus icon on the top-right corner of the page.
Once the organization is created, a team member can be invited by clicking the âPeopleâ tab on the navigation bar and then clicking the green âInvite memberâ button.
Exercise 1
One of the team members should create a GitHub organization for the project. Once the organization is created, invite other team members to the organization. When sending the invitation on the âRole in the organizationâ step, choose role âOwnerâ for each member of the team.
Exercise 2
One of the team members should create a GitHub repository for the project. Choose the âOwnerâ as the organization you created previously and give the repository a descriptive name and a description. This repository will become your projectâs repository where you start working on the project.
Exercise 3
Each team member should clone the projectâs GitHub repository for their local computer with the
git clone
command. Remember to use the HTTPS address of the GitHub repository with the command. See the Git instructions if you have trouble.
Exercise 4
Once every team member has the repository on their local computer, add a
README.md
file with some text in it to the repository folder and push it to GitHub. Then, each team member should do the following:
- Open the cloned repository folder with an editor such as Visual Studio Code and in Git Bash. Right-click the repository folder in the File Explorer and choose âGit Bash Hereâ
- Use the
git pull
command to pull the latest changes from GitHub- Make some change to the
README.md
file and push the changes to GitHub using thegit add
,git commit
andgit push
commands. See the Git instructions if you have trouble. If you arenât able to edit the file with Eclipse, use for example Visual Studio Code instead- Open the repository in GitHub and check in the
README.md
file that your changes has been successfully pushed to the remote GitHub repositoryIf you see
CONFLICT
in the command output, see the Git instructions to figure out how to solve conflicts.
GitHub Projects
GitHub Projects is a platform for managing taskboards. We will be using it for managing the user stories and tasks in our Product Backlog and Sprint Backlog.
Taskboards in GitHub Projects are called projects. Letâs create a project for our backlogs. Open your repository in GitHub and click the âProjectsâ tab. Then, click the green âNew projectâ button on the right. Click the arrow next to the button, if the button label is different. This should open a dialog. From the left side of the dialog, choose âBoardâ. This determines what the project will look like and you can change it later. Name the project âBacklogâ. Finally, click the âCreateâ button to create the project.
We now have a project with the default columns: âTodoâ, âIn progressâ and âDoneâ. The column will determine the status of the backlog items. We can edit the column names by clicking the three dots at the top-right corner of the column. We can add a new column by pressing the â+â button on the right side of the last column. Letâs change the columns so that they are the following from left to right:
- âProduct Backlogâ. This column is for the Product Backlog items. That is, items that are requirements for the project but arenât currently worked on. The items should be listed in the priority order (the âPâ of DEEP Product Backlog) defined by the Product Owner.
- âSprint Backlogâ. This column is for the Sprint Backlog items. That is, user stories and tasks that are chosen for the current Sprint. Top-priority items are chosen from the âProduct Backlogâ column and moved to this column during the Sprint Planning event.
- âIn progressâ. This column is for the items that some team member is currently working on.
- âIn reviewâ. This column is for items that require other Developerâs or Product Ownerâs acceptance before they can be moved to the âDoneâ column.
- âDoneâ. This column is for the items that have been completed.
Finally, letâs make sure that our project is public. Click the projectâs name and the projectâs settings should open. Scroll down to âDanger zoneâ section and choose âVisibilityâ as âPublicâ from the dropdown menu.
The project will be empty for now, but we will add some user stories and tasks for the project after the Sprint Planning event.
There are as many different backlog implementations as there are software development teams. The presented backlog implementation isnât the industry standard or the only correct one but perhaps a fairly good starting point. Scrum emphasizes constant process improvement and the backlog implementation should be constantly improved to better suit your teamâs needs.
Exercise 5
Create the âBacklogâ project as instructed above. Make sure that the project is public.
đââď¸ Sprint 1 planning
Hereâs how the Product Owner is describing the Sprint 1 goals in the Sprint Planning event:
âTo get started with the project, we need to implement a basic set of features for the teacher dashboard application so that the teachers can manage quizzes and their questions and answer options.
The teacher should be able to add a quiz using a form. A quiz has a name, for example âThe capital cities of Europeâ, a description, for example âLearn the capital cities of the European countriesâ and a published status. A quiz is either published or not. Each of these values should have a field in the form. The teacher should not be able to add a quiz with a blank name or description. The quiz should not be published by default.
The front page of the application should have a list of added quizzes. The list should display the information provided by the teacher while adding the quiz and the date when the quiz was added. The quizzes should be listed from newest to oldest, so that the latest quizzes are at the top of the list. The page should also have a link that takes the teacher to the page where they can add a quiz.
The teacher should be able to edit the information of a quiz if, for example they want to publish the quiz or change its name or description. The quiz list should have a link next to each quiz which takes the teacher to an edit form, where they can edit all the information of the quiz. The teacher should also be able to get rid of quizzes they donât need. There should be a delete button next to each quiz in the quiz list. When the user clicks the button, the quiz should be deleted.
The teacher should be able to add questions to a quiz. For example, the âThe capital cities of Europeâ quiz could have a question âWhat is the capital of Finland?â. A question has a question text, for example âWhat is the capital of Finland?â and a difficulty level. The difficulty level is either âEasyâ, âNormalâ or âHardâ. The default difficulty level is âNormalâ. The teacher should not be able to add a question with a blank question text or without a difficulty level.
The quiz also has a difficulty level which should be based on the average difficulty level of its questions. For example if a quiz has a âEasyâ and a âHardâ difficulty level question, the quiz difficulty should be âNormalâ. The quiz difficulty level should be displayed along with other quiz-related information in the quiz list.
The questions of a quiz should be listed on a separate page. Once a question has been added to a quiz, the teacher should be able to edit and delete it.
The teacher should be able to add answer options to a question. For example, the âWhat is the capital of Finland?â question could have answer options âTurkuâ, âHelsinkiâ and âTampereâ. An answer option has an answer option text, for example âTurkuâ, and a correctness status. Answer is either correct or not. For example, the âTurkuâ answer option would not be correct. The teacher should not be able to add an answer option with a blank answer option text. The answer option should not be correct by default.
The answer options of a question should be listed on a separate page. Once an answer option has been added to a question, the teacher should be able to delete it.â
â The Product Owner
After some discussion the Scrum Team planned the following user stories:
- As a teacher, I want to add a quiz so that students can learn about course-related topics
- As a teacher, I want to see a list of added quizzes so that I know which quizzes are added
- As a teacher, I want to edit a quiz so that I can change its information
- As a teacher, I want to delete a quiz so that I can get rid of quizzes I donât need
- As a teacher, I want to add a question to a quiz so that students can learn about course-related topics
- As a teacher, I want to see a list of quizâs questions so that I know which questions the quiz has
- As a teacher, I want to delete a quizâs question so that I can get rid of questions I donât need
- As a teacher, I want to edit a question so that I can change its information
- As a teacher, I want to add an answer option to a question so that students can learn about course-related topics
- As a teacher, I want to see a list of questionsâs answer options so that I know which answer options the question has
- As a teacher, I want to delete an answer option so that I can get rid of answer options I donât need
The order of the user stories represent the priotity provided by the Product Owner. That is, this should be the order of the user stories in the Product Backlog. The Developers should also implement the user stories in this order.
These are the user stories, that you will be working on as a team during this Sprint. The next step of the Sprint Planning event is to split these user stories into codings tasks.
Exercise 6
Choose the Scrum Master among the team members for the first Sprint. The Scrum Master should help other team members with following the Scrum process, for example by facilitating the teamâs meetings and making sure that the backlogs are kept up-to-date.
GitHub issues
GitHub issues are used to track ideas, feedback, tasks, or bugs for work on GitHub. Open source projects commonly use issues for feature suggestions and bug reports (something is not working as inteded). Here is an example of issues in the React libraryâs repository. We will use issues to organize the user stories, tasks and bug reports in our project.
Before we start creating issues, letâs add some labels so that we can categorize our issues. Open your repository in GitHub and click the âIssuesâ tab. Then, on the right, click the âLabelsâ button. So that we can separate the user story issues from other issues, letâs add a âuser storyâ label by clicking the âNew labelâ button.
If you donât see the âIssuesâ tab in the repository, follow this guide to enable the issues. In our case the âIssuesâ checkbox should be checked.
Exercise 7
Create the âuser storyâ label to classify user story related issues.
Next, we need to specify the Sprint the issue is worked on. We can use Sprint-specific milestones to group the issues based on a Sprint. Letâs create a milestone for the first Sprint. First, click the âIssuesâ tab to open the issues page. Then, click the âMilestonesâ button next to the âLabelsâ button. On the Milestones page, click the âCreate a new Milestoneâ button. Set the milestone title as âSprint 1â. You can also specify a due date and a description if you want. Finally, click the âCreate milestoneâ button to create the milestone.
Exercise 8
Create the âSprint 1â milestone to group the issues of the first Sprint.
Now that we have the âuser storyâ label and the âSprint 1â milestone, letâs create an issue for each user story. Click the âIssuesâ tab and click the green âNew issueâ button on the right. Set the issue title as âAs a teacher, I want to add a quiz so that students can learn about course-related topicsâ. With the description we can provide additional details if we canât fit everything in the title. On the right, click âLabelsâ and choose the âuser storyâ label which indicates that this issue is a user story. Then, click âProjectsâ and choose the âBacklogâ project. This will add the issue to the Backlog project. To specify the issueâs Sprint, click âMilestoneâ and choose âSprint 1â. Finally, click the âSubmit a new issueâ button to create the issue.
Next, letâs open the âProjectsâ tab and open the Backlog project. We should see that the issue we created is now in the project. We can move the issue to a column by dragging the issue card. This will change the status of the issue. Letâs move the issue we created to the âSprint Backlogâ column, which indicates that this user story is in the current Sprint.
By default we canât see the labels or the milestone on the issue cards. We can click on the arrow button next to âView 1â below the project name and click âFieldsâ under âConfigurationâ. There, check âLabelsâ and âMilestoneâ. Finally, click the green âSaveâ button to save the configuration.
Exercise 9
Create an issue for each user story. Add the âuser storyâ label for each issue. Set the milestone as âSprint 1â. Add the issues to the Backlog project and move them to the âSprint Backlogâ column.
The tasks that you come up with during the Sprint Planning event should not be set in stone. These tasks are there to get you started with implementing the user stories. You might come up with new tasks or notice that the current tasks need alterations during the actual implementation. In such case, do the necessary changes for the Sprint Backlog.
Use all the knowledge in your team and plan the tasks together.
Exercise 11
Initialize a Spring Boot backend application for the teacher dashboard for example using the Spring Initializr. Push the Spring Boot application to GitHub.
This your projectâs first task. Create an issue for the task. Set the milestone as âSprint 1â. Add the issue to the Backlog projectâs âSprint Backlogâ column.
Exercise 11
Read through the User stories and tasks section. Then, plan the tasks for the first user story, âAs a teacher, I want to add a quiz so that students can learn about course-related topicsâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Consider for example the following things in the tasks:
- What kind of data requirements does the user story have?
- What kind of user interface requirements does the user story have?
- What kind of controller requirements does the user story have?
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
Tips for the tasks:
- Implement appropriate validation for the user input. This guide covers the basics of the topic
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 11
Plan the tasks for the second user story, âAs a teacher, I want to see a list of added quizzes so that I know which quizzes are addedâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 12
Plan the tasks for the third user story, âAs a teacher, I want to edit a quiz so that I can change its informationâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 13
Plan the tasks for the fourth user story, âAs a teacher, I want to delete a quiz so that I can get rid of quizzes I donât needâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 14
Discuss how you will divide the the tasks of the first four user stories among the team members. For example, each team member could be responsible for the tasks of a single user story. Then, add an assignee for each issue. This can be done by opening the issue and clicking âAssigneesâ on the right. Then, choose your GitHub account from the dropdown menu. Issue can also have more than one assignee if multiple team members work on the same issue together.
When you complete a task, you should close the task related issue. This can be done by clicking the issue title in the Backlog project and clicking the âClose issueâ button. Also, move the issue to the âDoneâ column in the Backlog project.
Donât close the user story related issues before the Sprint Review event. The Product Owner needs to accept the user stories before they are completed. Once all user story related tasks are completed, move the user story related issue to the âIn reviewâ column.
While working on the tasks, keep the Sprint Backlog up-to-date:
- When you start working on a task, assign it to you and move it to the âIn progressâ column in the project
- When you complete a task, move it to the âDoneâ column in the project. Also remember to close the task related issue
- When all user story related tasks are completed, move the user story related issue to the âIn reviewâ column to wait for the Product Ownerâs review in the Sprint Review event
Use the Sprint Backlog to track the Sprint progress. Always start a team meeting by looking at the Sprint Backlog.
You can easily find the issues assigned to you by opening the âIssuesâ tab and choosing your GitHub account from the âAssigneeâ dropdown menu.
Tips for the teamwork
Hereâs a few tips before you start implementing the tasks:
- Use the full potential of your team and work together. Plan the tasks together, implement the tasks together and support each other
- Maintain active communication regarding the Sprint progress. Keeping the Sprint Backlog up-to-date is important but also share your progress and problems actively with your team members face-to-face or via Teams or other communication platform
- Push code to the GitHub repository often. Once you have some working code, use
git add
,git commit
,git push
commands to push the code to GitHub - Pull the code from the GitHub repository often. Run the
git pull
command to get the latest changes to your local computer - While pulling the code from the GitHub repository, youâll probably face merge conflicts. You can spot a merge conflict from the
git pull
command ouput:CONFLICT (content): Merge conflict in ...
. If you have trouble solving the merge conficts, see the Git instructions
The README file
The README.md
file we worked with previously has a special meaning in software development projects. When a software developer starts exploring a project, the first thing they should do is to look for the README file. This file should have all the relevant information about the project, for example:
- Whatâs the project about?
- How to use the project?
- How to develop the project?
- Who are the project contributors?
In GitHub, the README files commonly have the .md
extension. These are Markdown files. Markdown is markup language similar to HTML and you can use it to add formatting elements to plaintext text documents. Compared to HTML, Markdown syntax is much simpler and thatâs why it is an excellent choise for formatting text documents.
This guide demonstrates the Markdown syntax compared to HTML. As an example, hereâs what the React projectâs README.md
file looks like and hereâs what the Markdown markup looks like. You can use the Markdown Live Preview to try out different kind of Markdown markup.
Exercise 15
Open the
README.md
file for editing for example in GitHub or in Visual Studio Code. You might not be able to edit the file in Eclipse. Replace the current contents of the repositoryâsREADME.md
file with the following information using Markdown:
- At the beginning of the file add the project name âQuizzerâ as a heading.
- Below the heading add a short (a few sentences) description of the project as paragraphs. Check the project description for some inspiration.
- Below the description, add a subheading âTeam membersâ and below that add a list of each team memberâs name.
- Each team memberâs name should be a link to their GitHub profile page. The GitHub profile link is in format https://github.com/GITHUB_USERNAME, for example https://github.com/Kaltsoon
- Below the âTeam membersâ section, add a subheading âBacklogâ and below that add a link to the Backlog project created previously (open the Backlog project in GitHub and copy the URL from the web browserâs address bar).
Push the
README.md
file changes to GitHub and see that the file formatting looks correct in GitHub.
Daily Scrum
The Daily Scrum is a 15-minute event, commonly held on daily basis. The purpose of the Daily Scrum is for the Scrum Team to inspect and adapt its progress. During the event each team member typically answers the following three questions:
- What did you do previously?
- What will you do next?
- Are there any obstacles in your way?
For example this could be a one team memberâs statement during the Daily Scrum:
âYesterday I started implementing the task for the blog listing Thymeleaf template. Iâll continue working on that today. I had some trouble while trying to iterate a List in the Thymeleaf template. I donât remember the syntax. Could anyone have a look at it with me after the Daily Scrum?â
â Jane, one of the Developers
The Sprint Backlog should be open during the event so that the whole Scrum Team is up-to-date with Sprint Backlog updates and the Sprint progress.
A funny fact: it is common that during the Daily Scrum the whole Scrum Team is standing. This is why the Daily Scrum is often called the âdaily stand-upâ. The reason is very practical: the event tends to be shorter because standing for a long period of time can become tedious.
Exercise 16
Organize a Daily Scrum event at least once a week during each Sprint.
Exercise 17
Plan the tasks for the fifth user story, âAs a teacher, I want to add a question to a quiz so that students can learn about course-related topicsâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 18
Plan the tasks for the sixth user story, âAs a teacher, I want to see a list of quizâs questions so that I know which questions the quiz hasâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 19
Plan the tasks for the seventh user story, âAs a teacher, I want to delete a quizâs question so that I can get rid of questions I donât needâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
Exercise 20
Plan the tasks for the eight user story, âAs a teacher, I want to edit a question so that I can change its informationâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
Exercise 21
Plan the tasks for the ninth user story, âAs a teacher, I want to add an answer option to a question so that students can learn about course-related topicsâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 22
Plan the tasks for the tenth user story, âAs a teacher, I want to see a list of questionsâs answer options so that I know which answer options the question hasâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
The Scrum Teamâs UI Designerâs vision is that the implementation could look something like this:
Exercise 23
Plan the tasks for the eleventh user story, âAs a teacher, I want to delete an answer option so that I can get rid of answer options I donât needâ. Read the Product Ownerâs Sprint Planning description regarding the user story again and split it into small coding tasks.
Create an issue for each task. Set the milestone as âSprint 1â. Add the issues to the Backlog projectâs âSprint Backlogâ column.
Git branches
So far, we have only created commits for the main branch of our repository. Git branches allows us to diverge from the main branch commit history by creating a new branch. We can add commits for our branch without effecting the main branch commit history and at some point we merge the commits of a branch into the main branch.
Branches are commonly used to isolate work-in-progress code from the main branch. This can be for example the development of certain user story. Commonly, the main branch should only contain working code and deployment ready features. This means that the latest working version of our application can be found in the main branch at all times. We should be able to deploy this application for our users at any moment without issues. The Git workflow where feature development is isolated into a feature-specific branch is referred to as feature branch workflow. This workflow is a very common workflow in the industry.
A new branch can be created with the git branch <name-of-the-branch>
(replace the <name-of-the-branch>
with name of the branch) command in Git Bash. Letâs create a branch and name it our GitHub username with lowercase letters. First, pull the latest changes from GitHub using the git pull
command. Then, create the branch:
git branch <name-of-my-branch>
Typically, the branch name describes the feature developed in the branch or some other purpose of the branch, for example
delete-quiz
oradd-question
.
Now, letâs check the repositoryâs branches with the git branch
command. We should see that our branch is added to the list. We can also see that thereâs an astrisk symbol (*) before the main branch. This means that we are currently on the main branch. The current branch is also displayed in brackets in the Git Bash after the path to the current folder.
We can switch branches using the git checkout <name-of-the-branch>
command. Switch to the branch you just created:
git checkout <name-of-my-branch>
We usually want to create new branch of the main branch. This means that before creating a new branch with the
git branch <name-of-the-branch>
command, switch to the main branch by running thegit checkout main
command. If you are uncertain which is the current branch, check it with thegit branch
command.
Next, make some small change for the project, for example by changing a button text or color in the user interface or changing a variable name in a method. If thereâs some small code or user interface improvement you have in mind, this is the time to do it. You can also consider implementing one of the remaining user stories or tasks in a feature branch. Once you have made the change, check the status with git status
command, add the changes with the git add
command and create a commit with the git commit
command. Feel free to do multiple commits if needed.
Then letâs switch back to the main branch with the git checkout main
command. If we check for the changes we made in the other branch, we see that they are no longer present. Thatâs because the commits we made only exist in our other branch.
Letâs switch back to our branch with the git checkout
command. Then, push the changes to GitHub with the git push
command. We get the following error message:
fatal: The current branch kaltsoon has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin kaltsoon
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
The error means that the current branch is not in GitHub yet, just on our local computer. Letâs run the command that Git suggests:
git push --set-upstream origin <name-of-my-branch>
Now, letâs check that our branch is pushed to GitHub. Open the repository in GitHub and click the branch selector which says âmainâ above the file tree view in the âCodeâ tab. These instructions have more details, if you have trouble. We should see our branch there. Click the branch and check that the changes are visible in GitHub.
Exercise 24
Each team member should do the steps mentioned above to create their own branch named by their GitHub username and push it to GitHub.
We can also pull remote branches from GitHub to our local computer. Check the list of branches in GitHub and pick some other team memberâs branch. Then, to pull the remote branches from GitHub using the git pull
command. Finally, switch to the team memberâs branch:
git checkout <name-of-other-team-member-branch>
Merging branches and pull requests
Once we are happy with the changes we have made in the branch, we should merge it into the main branch. This basically means applying all the commits we have made for the branch to the main branch. For this we could use the git merge
command:
git checkout main
git merge <name-of-my-branch>
git push
But, GitHub supports a better way to merge branches using pull requests. Pull requests are ârequestsâ to merge a branch to another branch (commonly the main branch). The benefit over using the git merge
command is that pull requests provide a way to perform quality assurance, for example through code reviews. In a code review other team members inspect the chanhes introduced by the pull request and give constructive feedback. This feedback is used to improve the code quality and fix bugs and other implementation flaws.
Exercise 25
- Create a pull request for your branch by following these instructions. The pull request title should describe the changes, for example âChange the submit button color in the add quiz formâ. The description provides additional details
- Take a look at some other team memberâs pull request and conduct a code review by following these instructions. Pull the branch from GitHub to your local computer and take a look at the changes. If everything looks good, approve the changes with a short comment, such as âLooks good to meâ. Otherwise, request changes
- Once you have received an approving review from a team member for your pull request, merge it into the main branch by following these instructions. If the branch has conflicts with the main branch, check the section below
- Switch back to the main branch with the
git checkout main
command and pull the changes from GitHub with thegit pull
command. Make sure that you can see the changes made in your branch in the main branch as well
Resolving conflicts in branches
If the pull request canât be automatically merged due to conflicts, weâll need to solve them manually. First, switch to the main branch and pull the latest changes:
git checkout main
git pull
Then, switch to your branch and merge the main branch to it:
git checkout <name-of-my-branch>
git merge main
Finally, resolve the conflicts and add, commit and push the changes to GitHub. Now, we should be able to merge the pull request in GitHub.
Developer guide documentation
Now that we have implemented some features for our application that the users can use it is time to describe how to use the application. The developer guide is perhaps one of the most important pieces of documentation for the application. It will describe our fellow developers how to technically use the application. This means for example, how to start the application, how to package the application, and how to run tests.
The developer guide shouldnât make too many assumptions, for example, that the reader of the documentation happens to know that the application.properties
file needs alterations before the application can be started. If something needs to be done, even a simple thing, mention it. It is helpful not only for others but also for yourself. We should also describe the system requirements for the application. For example, the required Java version. You can find it in the pom.xml
file in the java.version
property.
Because developers use different IDEs, it is easier to describe how the application can be used using a command-line interface (such as Git Bash). On the command-line, we can use the Maven command mvn
or the alias ./mvnw
to run different Maven commands. Using ./mvnw
(the Maven wrapper) is a bit more convenient because it doesnât require Maven to be installed.
Hereâs an example of step by step instructions on how to start a Spring Boot application on the command-line:
- Start the application by running the
./mvnw spring-boot:run
command on the command-line in the repository folder - Once the application has started, visit http://localhost:8080 in a web browser to use the application
If you have trouble starting the application with the
./mvnw spring-boot:run
command, see if this solves the problem.
The description should be so clear that your fellow student who knows nothing about the project beforehand would be able to start the application.
Exercise 27
Write a developer guide documentation on how to start the backend application on the command-line to the
README.md
file. Also, mention the required Java version for the project. Add it under a âDeveloper guideâ subheading.For the sake of readability, code and command text is commonly highlighted (like in the example above). Hereâs how that is done in Markdown.
You can assume that the reader of the
README.md
file is a software developer who knows how to use a command-line interface, the basic Git commands and install the required Java version. Make sure that instructions on the developer guide work by cloning a new version of the repository and executing the steps on the developer guide one by one.
JAR
A JAR (Java Archive) is a package file format typically used to aggregate many Java class files and associated metadata and resources (such as CSS files, JavaScript files and other assets) into one file to distribute application software or libraries on the Java platform. If a user wants to use our application, instead of providing them with the entire source code, we can just provide a JAR file containing everything needed to run our application.
The name of the JAR file is specified by the artifactId
and the version
properties in the pom.xml
file. Set these properties as following:
<artifactId>quizzer</artifactId>
<version>0.0.1-SNAPSHOT</version>
We can generate a JAR file for the application with the following command:
./mvnw package
The command output will display the path to the generated JAR file.
If you have trouble generating the JAR file with the
./mvnw package
command, see if this solves the problem.
If the application is currently running, for example in Eclipse, stop it. Then, run java -jar target/quizzer-0.0.1-SNAPSHOT.jar
to run the application with the JAR file. Open the application in http://localhost:8080 and see that it is working.
Exercise 28
Generate a JAR file for the application and run the application using the JAR file. Add instructions on how to generate and run the application using the JAR file to the âDeveloper guideâ section in the
README.md
file.NB: The
target
folder (including the JAR file) should not be pushed to GitHub. The wholetarget
folder is commonly ignored by Git using a.gitignore
file. Weâll get to the purpose of this file later.
When you change the applicationâs code, you need to re-generate the JAR file with the
./mvnw package
command to have a JAR file for the latest version of the application.
Deployment
So far we have been using and developing our application in an isolated environment on our own computer. This environment used during the development of the application is referred to as the development environment. In the software development lifecycle the deployment phase is the phase in which the implemented software is distributed to the users. For example, a web application is published online so that users can access it with their web browsers. This environment is referred to as the production environment.
The deployment phase is crucial because unless users can use the application, it has no real value for the stakeholders. That is why in the agile software development process, deployment is done frequently, even on daily basis. In Scrum, the deployment should occur at least at the end of each Sprint. There are many platforms for deploying web applications, such as Heroku and Render. During the course, we will learn how to deploy our application to Render.
Letâs have a look, how we can deploy our application to Render so that the users can start using it. First, sign in to Render using your GitHub account. Then, we will need to set up a production database for our application. The H2 database is convenient in the development environment but not suitable for the production environment. We can create a PostgreSQL database instance in Render dashboard by clicking the âNewâ button on the navigation bar and choosing âPostgreSQLâ. Name the PostgreSQL instance âquizzer-databaseâ and the database âquizzerâ. Then, scroll to the bottom and click the âCreate databaseâ button.
Once the PostgreSQL instance has been created, open its information in the Render dashboard. In the PostgreSQL instanceâs page, scroll to âConnectionsâ section. Copy the values for âUsernameâ, âPasswordâ and âInternal Database URLâ and paste the values temporary to an editor. We will need these values soon.
Next, letâs add âinstructionsâ for Render on how to start our application to our project. Render supports deploying Docker containers which are isolated environments for running all kinds of applications. A Docker image is a set of instructions used to run containers. These instructions are defined with a Dockerfile. Add the following Dockerfile
file (the file name is just Dockerfile
without a file extension) to the root folder of the project (same folder that has the pom.xml
file):
FROM maven:3.8.7-openjdk-18-slim AS build
COPY . .
RUN mvn clean package -DskipTests
FROM openjdk:21-jdk-slim
COPY --from=build /target/quizzer-0.0.1-SNAPSHOT.jar quizzer.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","quizzer.jar"]
The Dockerfile
has some familiar commands. Basically we just generate a JAR file for the project and start the application using the JAR file.
Because we use PostgreSQL as the production database, we will need to specific production environment configuration. Add a file application-production.properties
to the src/main/resources
folder (same folder that has the application.properties
file) with the following content:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=${POSTGRES_URL}
spring.datasource.username=${POSTGRES_USERNAME}
spring.datasource.password=${POSTGRES_PASSWORD}
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=update
The values inside ${...}
are environment variables. We will define them in Render soon.
The PostgreSQL database requires a suitable driver for the application. Letâs add the PostgreSQL driver dependency to the <dependencies>
list in the pom.xml
file:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
If you use a CommandLineRunner
to initialize the database with test data each time the application starts, you will need to disable it in the production environment. This is because the application will restart multiple times, adding the same data to the database over and over again.
The easy way to solve this problem is to remove the CommandLineRunner
method and use an embedded H2 database instead of an in-memory database in the development environment. Embedded database is stored to a file so the data wonât vanish once the application is shut down. To use an embedded database, set the following properties in the application.properties
file:
spring.datasource.url=jdbc:h2:file:~/quizzer;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE
spring.datasource.username=admin
spring.datasource.password=password
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
This will save the database to a ~/quizzer.mv.db
file. If you want to reset the database and remove all the data, simply delete the file by running the rm ~/quizzer.mv.db
command on the command-line.
Now that we have the database-related changes in order, push these changes to GitHub before heading further.
Finally, for the application itself, we need to create a web service. Complete the following steps to create a web service in the Render dashboard:
- Click the âNewâ button on the navigation bar and choose âWeb Serviceâ
- Choose âBuild and deploy from a Git repositoryâ and click the âNextâ button
- In the create web service page, click âConfigure accountsâ in the âGithubâ section on the right. Choose your GitHub organization from the list, choose âAll repositoriesâ and click the âInstallâ button
- Back in the create web service page, choose your project repository in the âConnect a repositoryâ section by clicking the âConnectâ button next to the repositoryâs name
- Come up with a name for the web service that isnât already in use. The name will be visible in the applicationâs URL so try to come up with a sensible name
- Choose âDockerâ as the runtime in the dropdown menu
-
Click the âAdvancedâ button at the bottom of the page. In the advanced options section, click the âAdd environment variableâ button to add three environment variables (key, value):
POSTGRES_URL
: the internal URL in correct format of the PostgreSQL instance. The URL format isjdbc:postgresql://<url>
. Basically, you can take everything after the â@â symbol in the internal URL you copied previously and the environment variable value isjdbc:postgresql://<everything-after-the-@-symbol>
POSTGRES_USERNAME
: the username of the PostgreSQL instancePOSTGRES_PASSWORD
: the password of the PostgreSQL instanceSPRING_PROFILES_ACTIVE
: set asproduction
- Set âAuto-Deployâ as âNoâ from the dropdown menu
- Click the âCreate Web serviceâ button at the bottom of the page
Open the created web service in the Render dashboard. The deployment of the application should have started and it will take some time to finish. You can always deploy the application by clicking the âManual Deployâ button and choosing âDeploy latest commitâ. Once the deployment is complete the application will be accessible to everyone in the URL that is displayed under the web serviceâs name.
It might take a while for the application to open in the web browser.
Exercise 29
Deploy the backend application to a production environment. Add the production environment URL of the backend application (the web service URL in the Render dashboard) to the âDeveloper guideâ section in the
README.md
file.
Separate branch for the production code
A quite common practice is to separate the development and production code with separate branches. One such workflow is described in this article. We can do a bit simplified version of this workflow, by having the main branch for the development code an a production branch for the production code. Having a separate branch for the production code enables great features, such as quality assurance and automated deployments. We can deploy the application by simply merging the main branch to the production branch using a pull request.
Exercise 30
- Create a
production
branch of the main branch. Then, push the branch to GitHub using thegit push origin -u production
command- Open the backend web service in the Render Dashboard and go to the âSettingsâ page. In the âBuild & Deployâ section, set the âBranchâ as âproductionâ and âAuto-Deployâ as âYesâ
- Switch back to the main branch and make some small change in the code and push the changes to GitHub. Then, open a pull request. Set the base branch as the
production
branch and the compare branch as themain
branch.- Merge the pull request and check that the deployment works automatically
- Explain the purpose of the
main
and theproduction
branch in theREADME.md
file. How are these two separate branches used in your projectâs Git workflow?
When you want to deploy the application to the production environment, open a pull request as described above. Donât wait until the end of the Sprint for the deployment. Once you have a meaningful set of features implement, deploy the application and test that the new features work in the production environment.
GitHub release
Once the GitHub repositoryâs main branch has a working version of the application with the desired features at the end of the Sprint, we should release it for the users. GitHub release is a way to âfreezeâ the source code of a project at certain point of the commit history and to provide users a working version of the application.
Usually a new version of an application is released at the end of each Sprint. When we create a new release at the end of each Sprint, we will create a release history for the project. Users can easily browse and download the source code of different versions of the application by going through the release history.
Each release should at least include the name for the release and a short description describing the changes introduced in the release. For libraries the release name is commonly the version number of the release, for example â18.2.0â. We create a release for each Sprint, so we can name our releases based on the Sprint number, for example âSprint 1â.
As an example, here are the releases for the React library.
Exercise 31
Once you have implemented the user stories of the Sprint and the main branch has a working version of the application, create a GitHub release for the project as instructed in the GitHubâs documentation. Create a new tag called âsprint1â. The release title should be âSprint 1â. Give a brief description for the release that describes the features implemented during the Sprint.
Sprint Review
At the end of each Sprint, thereâs the Sprint Review event. During the Sprint Review, the Developers demonstrate the outcome of the Sprint for the Product Owner. This means that the Developers should demonstrate how the implemented user stories work in the userâs perspective. So, instead of showing the code, Developers should show how the user can use the new features of the application.
Sprint Review has a huge impact on the transparency of the process. Seeing how the application actually works also brings forth many new ideas for the upcoming Sprint Planning event.
Exercise 32
The Scrum Master should prepare the Sprint Review demonstration at the beginning of the next Sprint. The Scrum Master should make sure that they have a working version of the application either deployed to Render (preferred) or on their computer and they are able to show how the new features work in the userâs perspective. If possible, demonstrate the features in the production environment.
Prepare some sensible test data (no lorem ipsum, âasdâ, or âfoobarâ) for the Sprint Review. This means that you should add a few sensible quizzes using the application so that you can easily demonstrate the user stories.
Make sure that everything mentioned in the exercises is pushed to the projectâs GitHub repository before the Sprint 1 deadline on 22.4. at 12:00.