Mert Özen Further With Every Line

Blog

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

Series
16 posts found
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
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
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
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
.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
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
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
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 Environments: Protection Rules, Approvals and Deployment History
DevOps PART 09

GitHub Actions Environments: Protection Rules, Approvals and Deployment History

An environment is a named target that applies protection rules (required reviewers, wait timers, branch/tag policies) before a job reaches a runner, exposes its secrets only to that job and keeps a deployment history. Bookstore's staging/production deploy workflow, plan limits for private repositories, deployment: false, per-environment concurrency and queue: max; where act and actionlint stop, with real output.

8 Nov 2026 13 min 2
Deploying with GitHub Actions 1: Azure App Service with OIDC and Secretless Cloud Access
DevOps PART 10

Deploying with GitHub Actions 1: Azure App Service with OIDC and Secretless Cloud Access

With OIDC, every job gets a signed, short-lived token from GitHub, and Azure verifies it against a federated credential and grants access without a client secret. id-token: write, sub claim formats, the July 2026 subject change with IDs, custom property claims, deploying to a staging slot, smoke testing and swapping; AWS and Google Cloud equivalents.

8 Nov 2026 12 min 5
Deploying with GitHub Actions 2: Your Own Linux Server via SSH, Docker Images and GHCR
DevOps PART 11

Deploying with GitHub Actions 2: Your Own Linux Server via SSH, Docker Images and GHCR

Build the image once in GitHub Actions, push it to GHCR and send only the digest to the server over SSH; the server pulls it with Docker Compose and restarts. metadata-action, build-push-action and the gha cache backend (28 s down to 4 s), actions/attest, pinning known_hosts and what happens when the host key changes, rollback with .env.previous; real runs with act.

8 Nov 2026 12 min 4
Reducing Duplication in GitHub Actions: Composite Actions, Reusable Workflows and YAML Anchors
DevOps PART 12

Reducing Duplication in GitHub Actions: Composite Actions, Reusable Workflows and YAML Anchors

Use a composite action to share steps, a reusable workflow to share jobs that need environments and approvals, and YAML anchors to repeat a block within one file. Bookstore's dotnet-ci action and reusable-deploy workflow under act; the risks of secrets: inherit, environment secrets, the 10-level/50-workflow limits, the $/ syntax, versioning and why merge keys are not supported.

8 Nov 2026 11 min 4
Blog Map