Mert Özen Further With Every Line

Blog

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

Series
105 posts found
Secrets, Variables and GITHUB_TOKEN Permissions in GitHub Actions
DevOps PART 08

Secrets, Variables and GITHUB_TOKEN Permissions in GitHub Actions

Secrets are defined at organization, repository and environment level, the narrowest level wins, and they are masked in logs by text matching; derived values such as base64 and fields read out of JSON are not masked. With fake secrets in act we show ::add-mask::, secrets in if conditions, variables and an empty GITHUB_TOKEN, and cover least privilege with permissions, the vulnerability-alerts scope from September 2026, and GitHub App tokens instead of PATs.

8 Nov 2026 10 min 5
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 3
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 4
.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 3
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 4
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 4
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 4
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 3
Measuring and Speeding Up a Pipeline: DORA Metrics, Caching and Parallelism
DevOps PART 08

Measuring and Speeding Up a Pipeline: DORA Metrics, Caching and Parallelism

DORA's current five metrics (change lead time, deployment frequency, failed deployment recovery time, change fail rate, deployment rework rate) are calculated from deploy records and should be tracked as team-level trends; speeding up a pipeline starts with measuring. A single-file C# calculator, a real act measurement where a NuGet cache saved only 0.2 seconds of restore at a 2.3-second restore cost, cache key design, and the path filter trap.

8 Nov 2026 10 min 4
Pipeline Security and Secrets: Least Privilege, Short-Lived Credentials and Supply Chain
DevOps PART 07

Pipeline Security and Secrets: Least Privilege, Short-Lived Credentials and Supply Chain

The pipeline is the most powerful user, holding production keys; keeping secrets in a store, least privilege per job, short-lived tokens via OIDC instead of long-lived cloud keys and pinning actions to commit SHAs close most of the risk. Real act output showing a base64-encoded secret escaping masking, script injection caught by actionlint, fork PR risks, and a short look at SLSA v1.2 and SBOMs.

8 Nov 2026 9 min 5
Approvals, Gates and Deployment Controls: Adding People and Rules to a Pipeline
DevOps PART 06

Approvals, Gates and Deployment Controls: Adding People and Rules to a Pipeline

Automated gates (smoke tests, health checks, deploy freezes) should answer 'does this change work?', while a manual approval should answer 'now?'; DORA found no evidence that heavyweight external approvals lower the change fail rate. Real output showing that a Jenkins input step's submitter does nothing when everyone is an administrator, GitHub environment protection rules and Azure DevOps checks.

8 Nov 2026 10 min 4
Environments and Promotion: Dev, Test, Staging, Production and Configuration
DevOps PART 05

Environments and Promotion: Dev, Test, Staging, Production and Configuration

The same artifact moves through dev, test, staging and production without being rebuilt; the only thing that should change from step to step is configuration coming from the environment. Layered configuration in ASP.NET Core with appsettings.{Environment}.json and environment variables, a missing setting that fails at startup with ValidateOnStart, a difference inventory between staging and production, preview environments per PR, and masking non-prod data.

8 Nov 2026 9 min 6
Blog Map