Skip to content

Week 3 - CI/CD and more features

During this week you will enhance your application with more features and implement automated quality assurance through CI/CD pipelines.

Development requirements

This week you will receive additional user stories. You will need to implement these, keep in mind that all the week 2 user stories are also still required.

As a user, I want to receive clear feedback when something goes wrong so that I understand what happened and how to proceed.
  • All error messages should appear as popup notifications on the frontend.
  • Error messages should be clear and helpful (e.g., "Failed to upload image: file too large" rather than "Error 500").
  • Examples of errors to handle: failed post submission, image upload failures, network connectivity issues.
As a user, I want to control when error messages are dismissed so that I can read them at my own pace and not lose important information.
  • Error popups must have a close button that the user needs to click to dismiss them.
  • Popups should not auto-dismiss - user interaction is required.
As a user, I want to see the most current content when I refresh the page or interact with posts so that I'm always viewing up-to-date information.
  • When multiple users are using the application simultaneously, refreshing the page should show all recent posts and vote counts.
  • If someone else adds a post while I'm viewing the page, refreshing should show their new post.
  • If someone else votes on a post, refreshing should show the updated vote count.
  • The application should handle concurrent voting correctly (no lost votes or incorrect counts).
  • Consider race conditions when multiple users vote on the same post simultaneously.
As a user, I want to be able to add pictures to my posts so that I can share visual content along with my thoughts.
  • There should be an option to upload an image when creating a post.
  • Users can create posts with text only, image only, or both text and image.
  • Uploaded images should be displayed within the post on the main page.
  • Support common image formats (JPEG, PNG, GIF).
As a user, I want to see titles on posts so that I can quickly understand what each post is about before reading the full content.
  • There should be a separate input field for the post title when creating a post.
  • Titles should be mandatory.
  • The title should be displayed prominently above the post content.
  • Titles should have a character limit to ensure reasonable length for display.

Operations requirements

This week you should move your local code validation tools to the GitLab CI/CD environment.

GitLab CI/CD

GitLab CI/CD uses a .gitlab-ci.yml file in your repository root to define automated workflows called pipelines. By default, these pipelines run every time you push code. You should already have this file from the first week, where we asked you to create a simple "hello world" pipeline to verify your GitLab setup was working correctly.

But now, your pipeline must automatically run the same quality checks you've been doing locally: linting, formatting, and unit testing. The exact structure is flexible - you can organize these checks as separate stages or combine them into a single stage.

Pipeline failure policy

The pipeline must fail if ANY of these stages fail. This is a fundamental principle of CI/CD that prevents broken or poorly formatted code from entering your main branch.

Documentation requirements

What we expect your documentation to have?

Refer back to the week 2 documentation.

  • Do you need to update anything you wrote last week?

Pipeline documentation

  • How is your pipeline structured?
  • What does your pipeline do?

Image storage

  • How did you handle image storage?

Checkpoint analysis task

Every phase has written analysis alongside the implementation work. These are not documentation in the usual sense — they are not there to explain how to run your project. They are there to record your reasoning - what you chose, what you rejected, and what you expect to go wrong.

Each analysis is a separate file in your repository under (preferrably) docs/analysis/. You will return to these files in later phases, so write them for your future selves, not for us.

Important

Both files below are mandatory and are graded at checkpoint 1. Keep them under a single page each. Length is not the point, specificity and understanding is.

You are expected to be able to fully defend the results of these analysis tasks, if asked about.

Analysis 1: Stack and architecture

Your team has just made a set of decisions that you will live with for sixteen weeks. Write them down while you still remember why you made them.

The file must have these three sections:

  • What we chose

Languages, frameworks, tools - frontend and backend. How you store data and uploaded images. Repository layout: monorepo or multi-repo, frontend and backend separate or combined, and why.

  • What we rejected

For each major decision above, name at least one real alternative you considered and say why you did not pick it.

Failure

"We chose X because it is the best tool for the job" is not an answer. Neither is "we chose X because we already knew it" on its own - that is a perfectly valid reason, but then also analyse what it (might have) cost you and what trade-off did you make.

  • What we expect to be difficult in phase 3

In phase 2-3 you will package this application into containers and deploy it to Kubernetes. Some of the decisions you made this week will make that easy and some will make it painful. Name at least three things you expect to be painful, and explain why.

You have not containerised anything yet, so use these questions to find your answers:

  1. Where does your state live right now? Uploaded images, user sessions, the database itself. What is on the local filesystem?
  2. What is hardcoded? Hostnames, ports, file paths, database connection strings, URLs pointing at localhost.
  3. How does your application receive configuration? Could you change the database host without editing code?
  4. How many processes does it take to run your application? What starts them?
  5. What does your application write to disk while running? Logs, caches, temporary files, uploads.
  6. Where do your logs go, and in what format?
  7. How long does your application take to start from cold?
  8. If two copies of your backend ran at the same time, right now, what would break?

Tip

You are not expected to solve these problems this week. You are expected to see them coming. A prediction that turns out to be wrong is fine — a prediction that was never made is not.

Why are we asking for this in week 3?

In phases 2 and 3 you will re-read this file and write about what you actually hit. A prediction you wrote before you knew the answer is worth far more than a retrospective written afterwards, when everything looks obvious.

Analysis 2: Delivery metrics plan

You will report DORA metrics at the end of every phase. This week you decide how you will measure them, before you have anything to deploy to.

That is the hard part. All four DORA metrics are defined around the event "a change reached production." You have no production. So for each metric you must pick a proxy event that you can observe in GitLab today, and be honest about how that proxy differs from the real thing.

Your file must contain this table, filled in:

Metric Proxy event in phase 1 Where the data comes from How the proxy differs from the real metric Phase 2 definition
Deployment frequency (leave blank)
Lead time for changes (leave blank)
Change failure rate (leave blank)
Time to restore service (leave blank)

Rules for filling it in:

  • Proxy event must be a single, unambiguous event you can point at in GitLab. "When we finish a feature" is not observable. "Merge commit on main" is.
  • Where the data comes from must name the specific API endpoint, page, field or metric you have access to. You do not have to write the query itself, but you must know it exists.
  • How the proxy differs is the column we grade. One or two sentences. In which direction does your proxy bias the number, and which part of the real metric is invisible to you?
  • You may write "not measurable in phase 1" for a metric, as long as you state what would have to exist for it to become measurable. A well-argued "not measurable" beats a forced proxy event.
  • The last column stays empty. You fill it in during pahse 2, once you have somewhere to deploy.

Two traps

Lead time is not pipeline duration. Pipeline duration is one segment of it.

Do not count every failed pipeline as a change failure. A red pipeline on a feature branch is your quality gate doing its job - penalising yourself for that is measuring the opposite of what you want. Think about which pipeline failures represent a change that actually got through.

Tip

GitLab has a built-in DORA metrics feature, but it requires a paid tier. As we're looking to become professional DevOps engineers, work these metrics out by hand from the REST API or the pipeline list in the UI (where you can).

Tasks

  • Go through the user stories and implement all new features.
  • Set up a CI/CD pipeline that runs your code validation steps.
    • Formatting, linting and unit testing.
    • Pipeline must fail if any step fails.
  • Go through the documentation requirements and make sure to keep your documentation up to date.