Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Goal
<!-- What does this PR accomplish? 1 sentence. -->

## Changes
-

## Testing
<!-- How did you verify it? -->

## Checklist
- [ ] Title is a clear sentence (≤ 70 chars)
- [ ] Commits are signed (`git log --show-signature`)
- [ ] `submissions/labN.md` updated
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: QuickNotes CI

permissions:
contents: read

on:
pull_request:
paths:
- 'app/**'
- '.github/workflows/ci.yml'
branches:
- main
push:
branches:
- main
paths:
- 'app/**'
- '.github/workflows/ci.yml'

jobs:
vet:
runs-on: ubuntu-24.04
defaults:
run:
working-directory: ./app
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
with:
go-version: '1.24'
check-latest: false
- run: go vet ./...

test:
runs-on: ubuntu-24.04
defaults:
run:
working-directory: ./app
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
with:
go-version: '1.24'
check-latest: false
- run: go test -race -count=1 ./...

lint:
runs-on: ubuntu-24.04
defaults:
run:
working-directory: ./app
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
with:
go-version: '1.24'
check-latest: false
- uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee
with:
working-directory: ./app
79 changes: 79 additions & 0 deletions submissions/lab3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Platform choice

I picked GitHub way since I can login on it.

# Task 1 — Write the PR Gate

## 1.2: Design questions

1. Why pin the runner version (ubuntu-24.04) instead of ubuntu-latest? What breaks otherwise?

Answer:
When new Ubuntu version is released, some dependency updates can break my CI, which can result in long time of new code delivery.

2. Why split vet + test + lint into separate units? What would happen with one combined job?

Answer:
Firstly, splitting these jobs leads to parallelizing them and spending less time for CI. Secondly, if I run then in one job (hence sequentially), then if first job failed, I don't see the feedback for second and third.

3. GH path: what real attack does SHA pinning prevent? Cite the date + name of the incident from Lecture 3

Answer:
Incident CVE-2025-30066 took place on March 14, 2025. Attackers added malicious commit that printed secrets to logs. Ones that did not specify the exact SHA version of `tj-actions/changed-files` could automatically get malicious version of this action. That's why it's important to set exact hash of used GitHub Action.

4. GH path: what is permissions: and what's the principle behind it?

Answer:
In GitHub Actions `permissions` are used to set correct permissions for different operations within workflow. For example, `deployments: write` allows to create a new deployment. I decided to choose `contents: read` since I need nothing but listing the commits within `go vet`, `go test`, `go lint`.

## Link to green CI run

https://github.com/ilnarkhasanov/DevOps-Intro/actions/runs/27507991821/job/81302633680

## Screenshot of the failed run from 1.5, plus the fix commit

![alt text](static/failed-ci.png)

Fix commit: ![alt text](static/fix-commit.png)

## Branch protection rules

![alt text](static/branch-protection.png)

Additionally, I removed the possibility to bypass checks:

![alt text](static/no-bypass.png)

# Task 2 — Make It Fast and Smart

## Timing table

| Scenario | Wall-clock |
|----------|-----------:|
| Baseline: no cache, single Go version, no path filter | 36s |
| With cache | 41s |
| With cache + matrix | 40s |

## Description of optimizations

- Caching: actually there are no dependencies, therefore there is nothing to cache. Hence, adding hashing did not speed up CI. Probably, the caching work in CI is the reason why there are 5 seconds more.
- Matrix: matrix increased the time, but CI now compares several versions. It shifts-left the situation when our program fail on some Go versions.

## Design questions

Why cache go.sum-keyed inputs and not build outputs?

Answer:
`go.sum` can be used as a hash for cache and it does not depend on environment. Build outputs do. Therefore, better to use `go.sum`-keyed inputs.

What does `fail-fast: false` change in a matrix run, and when do you actually want fail-fast: true?

Answer:

`fail-fast: false` makes all matrix values run even if some of them fail. We want it if we want to get a feedback for all version. Probably we do not want it if jobs are expensive and we only care if anything is broken.

What's the risk of an attacker writing a cache from a malicious PR that protected branches later read?

Answer:

Attacker can craft a cache where backdoored package included. If this cache will be used on a protected branch, app can be deployed with attacker's code.
Binary file added submissions/static/branch-protection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added submissions/static/failed-ci.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added submissions/static/fix-commit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added submissions/static/no-bypass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.