Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
9 posts found #ci
GitHub Actions in a .NET + Angular Monorepo: Path Filters, Passing Artifacts and a Single Release Package
DevOps PART 07

GitHub Actions in a .NET + Angular Monorepo: Path Filters, Passing Artifacts and a Single Release Package

Path-filtered separate workflows leave required checks pending; in a monorepo, a single workflow with a changes job that decides via git diff and an always-running summary job (ci-ok) fixes that. We carry Angular's dist into the .NET publish's wwwroot with an artifact, produce a single release zip on a tag push, and explain artifact versus cache and a GitHub Release with gh release create, using act output.

8 Nov 2026 10 min 4
Angular CI with GitHub Actions: setup-node, npm ci, Lint, Vitest, Build Budgets and Playwright
DevOps PART 06

Angular CI with GitHub Actions: setup-node, npm ci, Lint, Vitest, Build Budgets and Playwright

In an Angular 22 CI, read the Node version from devEngines in package.json with setup-node@v7, install from the lock file with npm ci, run ng lint, Vitest and ng build with budgets, and run Playwright e2e with the API and a PostgreSQL service container. With act output we show why setup-node's automatic npm cache did not turn on in a monorepo, the lock drift error, a Node version mismatch and the effect of the browser cache.

8 Nov 2026 12 min 5
.NET CI with GitHub Actions: setup-dotnet, global.json, NuGet Cache, Test Reports and Coverage
DevOps PART 05

.NET CI with GitHub Actions: setup-dotnet, global.json, NuGet Cache, Test Reports and Coverage

In a .NET 10 CI, pin the SDK with global.json and setup-dotnet@v6, restore with lock files and --locked-mode, key the NuGet cache to the lock hash, and gate with dotnet format and -warnaserror. We produce TRX and Cobertura reports with xUnit v3 on Microsoft.Testing.Platform, write them to the job summary and keep them with upload-artifact, and show act's v7 artifact limit and the Linux file-name pitfall with real output.

8 Nov 2026 11 min 4
Jobs in GitHub Actions: needs, matrix, concurrency, timeouts and Service Containers
DevOps PART 04

Jobs in GitHub Actions: needs, matrix, concurrency, timeouts and Service Containers

Jobs run in parallel by default; needs builds a DAG, and everything depending on a failed job is skipped. We split the Bookstore CI into format, unit-test (OS matrix), integration-test (PostgreSQL 16/17/18 service container), web-build and publish jobs and run it with act, covering include/exclude, fail-fast, max-parallel, concurrency, timeout-minutes, continue-on-error and the service command/entrypoint keys from April 2026.

8 Nov 2026 11 min 5
Expressions, Contexts and Variables in GitHub Actions: if, outputs and GITHUB_ENV
DevOps PART 03

Expressions, Contexts and Variables in GitHub Actions: if, outputs and GITHUB_ENV

Expressions inside ${{ }} read values from contexts (github, env, vars, steps, needs, inputs…), use loose comparison and drive if: conditions. With act output we show why text outside ${{ }} in if is always true, the contains/fromJSON/hashFiles/case functions, moving data with GITHUB_OUTPUT and GITHUB_ENV, a test table with GITHUB_STEP_SUMMARY, and always versus !cancelled.

8 Nov 2026 11 min 5
GitHub Actions Triggers: push, pull_request, workflow_dispatch, schedule and Filters
DevOps PART 02

GitHub Actions Triggers: push, pull_request, workflow_dispatch, schedule and Filters

The events and filters under on decide when a workflow runs: branches, tags, paths and ! negation for push and pull_request, activity types, workflow_dispatch inputs, timezone-aware schedules, workflow_run, repository_dispatch and merge_group. With real output we show the trap of reading booleans via github.event.inputs, the trigger mistakes actionlint catches, and why act does not evaluate filters.

8 Nov 2026 12 min 5
What Is GitHub Actions? Your First CI with Workflows, Events, Jobs, Steps and Runners
DevOps PART 01

What Is GitHub Actions? Your First CI with Workflows, Events, Jobs, Steps and Runners

GitHub Actions is a CI/CD platform that runs the YAML workflows under .github/workflows on runners in response to repository events. We write a first workflow that restores, builds and unit-tests the Bookstore API, try it locally with act and actionlint, and cover uses versus run, the run log, re-runs and the reasoning behind the Web API 31 workflow.

8 Nov 2026 13 min 5
From ADR to Automated Check: Verifying Decisions with Fitness Functions and CI
Software Architecture PART 06

From ADR to Automated Check: Verifying Decisions with Fitness Functions and CI

The Confirmation section of every ADR is the specification of a fitness function: a decision is checked on every PR, on a schedule, continuously in production, or lands on a short manual list. At Bookstore we verify the public API decision with oasdiff, the bundle size decision with Angular budgets, migration reversibility with an xUnit test and the .NET support window with a weekly check, all with real output.

8 Nov 2026 15 min 5
Keeping Architecture Healthy Over Time: Architecture Erosion and Fitness Functions
Software Architecture PART 09

Keeping Architecture Healthy Over Time: Architecture Erosion and Fitness Functions

Architectural decisions are protected not by code review but by fitness functions that run on every PR: a closed-layer rule with ArchUnitNET, a coupling threshold with a ratchet and a performance test that counts queries catch a PR that passes the build but breaks the architecture. Erosion and drift, kinds of fitness functions, a GitHub Actions step and a roadmap for the category.

7 Nov 2026 13 min 6
Blog Map