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
54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: CI
on:
push:
branches:
- main
paths:
- app/**
- .github/workflows/ci.yml
pull_request:
branches:
- main
paths:
- app/**
- .github/workflows/ci.yml
workflow_dispatch:
jobs:
test:
name: Run ${{ matrix.target }} for Go ${{ matrix.version }}
runs-on: ubuntu-24.04
permissions:
contents: read
strategy:
fail-fast: false
matrix:
version: ['1.24', '1.25']
target: ['test', 'vet', 'lint']
include:
- target: test
cmd: go test -race -count=1 ./...
- target: vet
cmd: go vet ./...
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: ${{ matrix.version }}
cache: true
cache-dependency-path: app/go.mod

- name: Run golangci-lint
if: matrix.target == 'lint'
uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1
with:
version: v2.5.0
working-directory: app

- name: Run ${{ matrix.target }}
if: matrix.target != 'lint'
run: |
cd app
${{ matrix.cmd }}
Binary file added submissions/lab3-blocked-merge.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/lab3-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/lab3-failed-run-log.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/lab3-merge-allowed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions submissions/lab3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Lab 3 submission
### The path
I have chosen GitHub path, because it works for me, and I already have an account.

### Branch protection rule
![](./lab3-branch-protection.png)

### Failed run + fix
Failed run prevents from merging:\
![](./lab3-blocked-merge.png)

Failed run log:\
![](./lab3-failed-run-log.png)

After fix:\
![](./lab3-merge-allowed.png)

[Link to the green run](https://github.com/arsenez2006/DevOps-Intro/actions/runs/27502050568)

### Design questions
- a) `latest` tag is a moving target. When GitHub upgrades the underlying runner image version, our workflow inherits it. Sudden updates may introduce breaking changes in pre-installed software, leading to pipeline failures.
- b) One combined job runs sequentially, while separate units run concurrently, significantly reducing total pipeline execution time. If a single formatting commit triggers a combined job, where the lint error appears at the end of a 15-minute test suite run, the entire pipeline fails late. Furthermore, a failure in an early step might prevent subsequent steps from running at all, hiding other errors.
- c) SHA pinning prevents Supply Chain Attacks via tag mutability. Tags may be overwritten by a malicious actor, making our pipeline inherit the compromised code (In March 2025, the popular tj-actions/changed-files action was compromised; the attacker rewrote all tags to a malicious version, leaking secrets from thousands of public CI runs). A cryptographic SHA is immutable and cannot be spoofed.
- d) `permissions:` is the runner access configuration for workflows. On workflows initiation, GitHub automatically issues a short-lived access token for the runner. The runner access token permissions may be configured the `permissions:` directive. By explicitly defining permissions, we ensure that even if an attacker successfully injects malicious code into the runner, they cannot abuse the token to gain full access to the repository.
- f) Caching `go.sum`-keyed inputs ensures strict environmental reproducibility by fixing the dependency tree. Conversely, caching build outputs is unreliable because artifacts depend on host-specific hardware, compiler versions, and system flags, which often lead to invalid states when restored on different runners.
- g) `fail-fast: false` ensures that all matrix jobs run to completion even if one fails, allowing us to see the full scope of potential issues. `fail-fast: true` should be used during active development or PRs to stop the pipeline immediately upon the first error, which saves compute costs and provides faster feedback.
- h) An attacker could attempt to "poison" the cache by writing malicious artifacts from a PR that a protected branch might later read. GitHub mitigates this risk through strict scope isolation: workflows from PRs can read caches from the target branch, but they are explicitly forbidden from writing to or overwriting caches scoped to that protected base branch.

### Pipeline Measurements
<!-- baseline = 23 + 28 + 29 = 1m20s, real = 37
caching = 23 + 24 + 13 = 1m, real = 33
caching + version matrix = 13 + 14 + 24 + 26 + 19 + 12 = 1m48s, real = 30 -->
| Scenario | Wall-clock |
|----------|-----------|
| Baseline (no cache, single Go version, no path filter) | 37 s |
| With cache | 33 s |
| With cache + matrix | 30 s |

### Pipeline optimizations
- Every pipeline job are executed concurrently, reducing overall wall-time
- Build inputs (`setup-go` and `golandci-lint`) are cached