From 0846dbb758ba788f969a381c56498920ee0f9562 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Thu, 8 May 2025 22:05:30 +0200 Subject: [PATCH 01/13] docs(pipeline): add design plan for PipelineExecutor class - Introduce a detailed plan for the PipelineExecutor class - Describe its purpose, interface, hooks, and internal workflow - Highlight advantages such as decoupling, testability, and extensibility - Will be removed before merge --- docs/pipeline_executor_plan.md | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/pipeline_executor_plan.md diff --git a/docs/pipeline_executor_plan.md b/docs/pipeline_executor_plan.md new file mode 100644 index 0000000..8fb6b0a --- /dev/null +++ b/docs/pipeline_executor_plan.md @@ -0,0 +1,72 @@ +# 🧩 Plan: `PipelineExecutor` + +## 🎯 Ziel +Eine eigenständige, testbare Klasse zur Ausführung einer Middleware- und Handler-Pipeline, die: +- Linear und sauber das `next()`-Verhalten abbildet +- Typvalidierung durchführt (`isMiddleware`, `isHandler`) +- Fehler behandelt und an konfigurierbare Handler weiterleitet +- Optionale Hooks zur Tracing-Integration bietet (z. B. für Zeitmessung, Logging) +- Am Ende eine dekorierte `Response` zurückliefert + +--- + +## 🧩 Schnittstelle (API) + +```ts +class PipelineExecutor { + constructor(cfg: IHttpKernelConfig); + + run( + ctx: TContext, + middleware: Middleware[], + handler: Handler, + hooks?: IPipelineHooks, // optional + ): Promise; +} +``` + +--- + +## 🪝 Hook-Schnittstelle (`IPipelineHooks`) + +```ts +interface IPipelineHooks { + onPipelineStart?(ctx: TContext): void; + onStepStart?(name: string | undefined, ctx: TContext): void; + onStepEnd?(name: string | undefined, ctx: TContext, duration: number): void; + onPipelineEnd?(ctx: TContext, totalDuration: number): void; +} +``` + +- `name` ist `undefined`, wenn keine `.name` am Handler/Middleware gesetzt ist +- Diese Hooks ermöglichen später Logging, Zeitmessung, Statistiken etc. +- Der `TraceManager` wird dieses Interface implementieren + +--- + +## 🛠️ Interne Aufgaben / Ablauf + +1. `run(...)` beginnt mit Aufruf `onPipelineStart(ctx)` +2. Zeitmessung (`performance.now()`) +3. Dispatcher-Funktion führt jede Middleware mit `next()`-Kette aus +4. Vor jedem Aufruf: `onStepStart(name, ctx)` +5. Nach jedem Aufruf: `onStepEnd(name, ctx, duration)` +6. Nach letztem Handler: `onPipelineEnd(ctx, totalDuration)` +7. Ergebnis wird durch `cfg.decorateResponse(res, ctx)` geschickt +8. Im Fehlerfall: `cfg.httpErrorHandlers[500](ctx, error)` + +--- + +## ✅ Vorteile + +- `HttpKernel` ist von Ausführungsdetails entkoppelt +- Tracing-/Logging-System kann ohne Invasivität angeschlossen werden +- Sehr gut testbar (z. B. Middleware-Mock + Hook-Aufrufe prüfen) +- Erweiterbar für Timeout, Async-Context, Abbruchlogik etc. + +--- + +## 📦 Dateiname-Vorschlag + +- `src/Core/PipelineExecutor.ts` oder +- `src/HttpKernel/PipelineExecutor.ts` -- 2.49.1 From 3f114bb68d94c48a53514752d57cb4f01adeaae3 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 16:21:16 +0200 Subject: [PATCH 02/13] feat(pipeline): add configuration and hooks for pipeline execution - Introduce `IPipelineExecutorConfig` to enable customizable pipeline behavior - Add `IPipelineHooks` interface for tracing and monitoring lifecycle events - Define callback types for pipeline start, step execution, and completion - Export new types and interfaces for broader integration within the system --- src/Interfaces/IPipelineExecutorConfig.ts | 33 +++++++++++++++ src/Interfaces/IPipelineHooks.ts | 36 +++++++++++++++++ src/Interfaces/mod.ts | 2 + src/Types/PipelineHooks.ts | 49 +++++++++++++++++++++++ src/Types/mod.ts | 6 +++ 5 files changed, 126 insertions(+) create mode 100644 src/Interfaces/IPipelineExecutorConfig.ts create mode 100644 src/Interfaces/IPipelineHooks.ts create mode 100644 src/Types/PipelineHooks.ts diff --git a/src/Interfaces/IPipelineExecutorConfig.ts b/src/Interfaces/IPipelineExecutorConfig.ts new file mode 100644 index 0000000..616d716 --- /dev/null +++ b/src/Interfaces/IPipelineExecutorConfig.ts @@ -0,0 +1,33 @@ +import { ResponseDecorator } from '../Types/ResponseDecorator.ts'; +import { IContext } from './IContext.ts'; +import { IHttpErrorHandlers } from './IHttpErrorHandlers.ts'; +import { IPipelineHooks } from './IPipelineHooks.ts'; + +/** + * Configuration object for the PipelineExecutor, defining how to handle + * errors, responses, and tracing hooks. + * + * This allows the execution logic to remain decoupled from kernel-level behavior + * while still supporting custom behavior injection. + * + * @template TContext - The context type propagated during pipeline execution. + */ +export interface IPipelineExecutorConfig { + /** + * Optional function used to transform or decorate the final Response object + * before it is returned to the client. + */ + decorateResponse?: ResponseDecorator; + + /** + * Optional map of error handlers, keyed by HTTP status codes (e.g., 404, 500). + * These handlers are invoked if an error occurs during middleware or handler execution. + */ + errorHandlers?: IHttpErrorHandlers; + + /** + * Optional hooks that allow tracing and lifecycle monitoring during pipeline execution. + * Each hook is called at a specific phase of the middleware/handler lifecycle. + */ + pipelineHooks?: IPipelineHooks; +} diff --git a/src/Interfaces/IPipelineHooks.ts b/src/Interfaces/IPipelineHooks.ts new file mode 100644 index 0000000..32a979a --- /dev/null +++ b/src/Interfaces/IPipelineHooks.ts @@ -0,0 +1,36 @@ +import { + OnPipelineEnd, + OnPipelineStart, + OnStepEnd, + OnStepStart, +} from '../Types/mod.ts'; +import { IContext } from './IContext.ts'; + +/** + * A set of optional hook functions that can be triggered during pipeline execution. + * These hooks allow tracing, performance measurement, and logging to be integrated + * without altering middleware or handler logic. + * + * @template TContext - The custom context type used within the application. + */ +export interface IPipelineHooks { + /** + * Triggered once before any middleware or handler is executed. + */ + onPipelineStart?: OnPipelineStart; + + /** + * Triggered immediately before each middleware or handler runs. + */ + onStepStart?: OnStepStart; + + /** + * Triggered immediately after each middleware or handler has finished executing. + */ + onStepEnd?: OnStepEnd; + + /** + * Triggered after the entire pipeline completes execution. + */ + onPipelineEnd?: OnPipelineEnd; +} diff --git a/src/Interfaces/mod.ts b/src/Interfaces/mod.ts index 7c235d9..67856a0 100644 --- a/src/Interfaces/mod.ts +++ b/src/Interfaces/mod.ts @@ -5,6 +5,8 @@ export type { IHttpErrorHandlers } from './IHttpErrorHandlers.ts'; export type { IHttpKernel } from './IHttpKernel.ts'; export type { IHttpKernelConfig } from './IHttpKernelConfig.ts'; export type { IInternalRoute } from './IInternalRoute.ts'; +export type { IPipelineExecutorConfig } from './IPipelineExecutorConfig.ts'; +export type { IPipelineHooks } from './IPipelineHooks.ts'; export type { IRouteBuilder, IRouteBuilderFactory } from './IRouteBuilder.ts'; export { isDynamicRouteDefinition, diff --git a/src/Types/PipelineHooks.ts b/src/Types/PipelineHooks.ts new file mode 100644 index 0000000..f1b0ce1 --- /dev/null +++ b/src/Types/PipelineHooks.ts @@ -0,0 +1,49 @@ +import { IContext } from '../Interfaces/mod.ts'; + +/** + * A callback invoked when the middleware pipeline starts. + * + * @template TContext - The context type passed throughout the pipeline. + * @param ctx - The context object for the current request. + */ +export type OnPipelineStart = ( + ctx: TContext, +) => void; + +/** + * A callback invoked immediately before a middleware or handler is executed. + * + * @template TContext - The context type passed throughout the pipeline. + * @param name - Optional name of the current middleware or handler, if defined. + * @param ctx - The context object for the current request. + */ +export type OnStepStart = ( + name: string | undefined, + ctx: TContext, +) => void; + +/** + * A callback invoked immediately after a middleware or handler has completed. + * + * @template TContext - The context type passed throughout the pipeline. + * @param name - Optional name of the current middleware or handler, if defined. + * @param ctx - The context object for the current request. + * @param duration - Execution time in milliseconds. + */ +export type OnStepEnd = ( + name: string | undefined, + ctx: TContext, + duration: number, +) => void; + +/** + * A callback invoked after the entire pipeline has completed execution. + * + * @template TContext - The context type passed throughout the pipeline. + * @param ctx - The context object for the current request. + * @param totalDuration - Total execution time of the pipeline in milliseconds. + */ +export type OnPipelineEnd = ( + ctx: TContext, + totalDuration: number, +) => void; diff --git a/src/Types/mod.ts b/src/Types/mod.ts index c159495..98da911 100644 --- a/src/Types/mod.ts +++ b/src/Types/mod.ts @@ -39,6 +39,12 @@ export type { HttpStatusCode } from './HttpStatusCode.ts'; export { isMiddleware } from './Middleware.ts'; export type { Middleware } from './Middleware.ts'; export type { Params } from './Params.ts'; +export type { + OnPipelineEnd, + OnPipelineStart, + OnStepEnd, + OnStepStart, +} from './PipelineHooks.ts'; export type { Query } from './Query.ts'; export type { RegisterRoute } from './RegisterRoute.ts'; export type { ResponseDecorator } from './ResponseDecorator.ts'; -- 2.49.1 From 8f94cc915c75a11efa1a8e3bdc51ffea9c2f19b5 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 16:34:19 +0200 Subject: [PATCH 03/13] chore(workflows): refine branch handling in release process - Adjusts workflow to support pushes from all branches - Ensures main branch-specific conditions for version detection - Modifies changelog and release steps for non-main branch handling --- .gitea/workflows/release.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 0d55559..0486dd7 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -4,10 +4,12 @@ on: push: branches: - main + - '**' jobs: detect-version-change: runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' outputs: version_changed: ${{ steps.check.outputs.version_changed }} steps: @@ -35,7 +37,7 @@ jobs: changelog-only: needs: detect-version-change - if: needs.detect-version-change.outputs.version_changed == 'false' + if: github.ref != 'refs/heads/main' || needs.detect-version-change.outputs.version_changed == 'false' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -75,12 +77,12 @@ jobs: echo "No changes to commit" else git commit -m "chore(changelog): update unreleased changelog" - git push origin main + git push origin "${GITHUB_REF##refs/heads/}" fi release: needs: detect-version-change - if: needs.detect-version-change.outputs.version_changed == 'true' + if: needs.detect-version-change.outputs.version_changed == 'true' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 -- 2.49.1 From 927a9081d4f363202520d017eb424c7c097ced94 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 16:50:41 +0200 Subject: [PATCH 04/13] feat(interfaces): add pipeline executor interface - Introduce `IPipelineExecutor` to define pipeline execution - Add `PipelineExecutorFactory` for instantiating pipeline executors - Export new types in the interfaces module for external use --- src/Interfaces/IPipelineExecutor.ts | 50 +++++++++++++++++++++++++++++ src/Interfaces/mod.ts | 4 +++ 2 files changed, 54 insertions(+) create mode 100644 src/Interfaces/IPipelineExecutor.ts diff --git a/src/Interfaces/IPipelineExecutor.ts b/src/Interfaces/IPipelineExecutor.ts new file mode 100644 index 0000000..a25ce09 --- /dev/null +++ b/src/Interfaces/IPipelineExecutor.ts @@ -0,0 +1,50 @@ +import { Handler, Middleware } from '../Types/mod.ts'; +import { IContext } from './IContext.ts'; +import { IPipelineExecutorConfig } from './IPipelineExecutorConfig.ts'; + +/** + * Constructor type for a class implementing the IPipelineExecutor interface. + * + * This can be used for dependency injection, factory-based initialization, + * or dynamic instantiation of pipeline executors. + * + * @template TContext - The extended context type passed through the pipeline. + */ +export interface PipelineExecutorFactory { + /** + * Creates a new instance of a pipeline executor. + * + * @param config - Configuration used to control error handling, + * response decoration and lifecycle hooks. + */ + new ( + config: IPipelineExecutorConfig, + ): IPipelineExecutor; +} + +/** + * Defines the contract for executing a middleware and handler pipeline. + * + * The pipeline is responsible for: + * - Executing middleware in order with `next()` chaining + * - Invoking the final handler + * - Applying optional lifecycle hooks + * - Producing and decorating a Response + * + * @template TContext - The context type flowing through the pipeline. + */ +export interface IPipelineExecutor { + /** + * Executes the middleware pipeline and returns the final Response. + * + * @param ctx - The context object representing the current HTTP request state. + * @param middleware - An ordered array of middleware functions to be executed. + * @param handler - The final route handler to be called after all middleware. + * @returns A Promise resolving to the final HTTP Response. + */ + run( + ctx: TContext, + middleware: Middleware[], + handler: Handler, + ): Promise; +} diff --git a/src/Interfaces/mod.ts b/src/Interfaces/mod.ts index 67856a0..ab31600 100644 --- a/src/Interfaces/mod.ts +++ b/src/Interfaces/mod.ts @@ -5,6 +5,10 @@ export type { IHttpErrorHandlers } from './IHttpErrorHandlers.ts'; export type { IHttpKernel } from './IHttpKernel.ts'; export type { IHttpKernelConfig } from './IHttpKernelConfig.ts'; export type { IInternalRoute } from './IInternalRoute.ts'; +export type { + IPipelineExecutor, + PipelineExecutorFactory, +} from './IPipelineExecutor.ts'; export type { IPipelineExecutorConfig } from './IPipelineExecutorConfig.ts'; export type { IPipelineHooks } from './IPipelineHooks.ts'; export type { IRouteBuilder, IRouteBuilderFactory } from './IRouteBuilder.ts'; -- 2.49.1 From abd2d6e8402662f863d9974aaa0bc228a4777724 Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 16:59:53 +0200 Subject: [PATCH 05/13] fix(workflows): ensure version detection output is always set - Move VERSION file change detection behind a branch guard (main only) - Use a fallback in the output step to ensure 'version_changed' is always defined - Prevent job skipping and output access errors in feature branches --- .gitea/workflows/release.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 0486dd7..3743270 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -9,32 +9,36 @@ on: jobs: detect-version-change: runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' outputs: - version_changed: ${{ steps.check.outputs.version_changed }} + version_changed: ${{ steps.set.outputs.version_changed }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check if VERSION file changed - id: check + if: github.ref == 'refs/heads/main' run: | echo "🔍 Vergleich mit github.event.before:" echo "Before: ${{ github.event.before }}" echo "After: ${{ github.sha }}" - + echo "📄 Changed files between before and after:" git diff --name-only ${{ github.event.before }} ${{ github.sha }} || echo "(diff failed)" if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^VERSION$'; then - echo "✅ VERSION file was changed between before and after" - echo "version_changed=true" >> $GITHUB_OUTPUT + echo "✅ VERSION file was changed" + echo "VERSION_CHANGED=true" >> $GITHUB_ENV else - echo "ℹ️ VERSION file not changed between before and after" - echo "version_changed=false" >> $GITHUB_OUTPUT + echo "ℹ️ VERSION file not changed" + echo "VERSION_CHANGED=false" >> $GITHUB_ENV fi + - name: Set output (always) + id: set + run: | + echo "version_changed=${VERSION_CHANGED:-false}" >> $GITHUB_OUTPUT + changelog-only: needs: detect-version-change if: github.ref != 'refs/heads/main' || needs.detect-version-change.outputs.version_changed == 'false' -- 2.49.1 From 32f3fe5f52d675702d3c81c711086bb54ce393f7 Mon Sep 17 00:00:00 2001 From: ghost-bot Date: Sat, 10 May 2025 15:01:16 +0000 Subject: [PATCH 06/13] chore(changelog): update unreleased changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a97511..bffe8ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,19 +6,27 @@ All notable changes to this project will be documented in this file. ### 🚀 Features +- *(interfaces)* Add pipeline executor interface - ([927a908](https://git.0xmax42.io/maxp/http-kernel/commit/927a9081d4f363202520d017eb424c7c097ced94)) +- *(pipeline)* Add configuration and hooks for pipeline execution - ([3f114bb](https://git.0xmax42.io/maxp/http-kernel/commit/3f114bb68d94c48a53514752d57cb4f01adeaae3)) - *(workflows)* Add CI for Deno project tests - ([9d5db4f](https://git.0xmax42.io/maxp/http-kernel/commit/9d5db4f414cf961248f2b879f2b132b81a32cb92)) +### 🐛 Bug Fixes + +- *(workflows)* Ensure version detection output is always set - ([abd2d6e](https://git.0xmax42.io/maxp/http-kernel/commit/abd2d6e8402662f863d9974aaa0bc228a4777724)) + ### 🚜 Refactor - *(workflows)* Rename changelog file for consistency - ([b9d25f2](https://git.0xmax42.io/maxp/http-kernel/commit/b9d25f23fc6ad7696deee319024aa5b1af4d98c0)) ### 📚 Documentation +- *(pipeline)* Add design plan for PipelineExecutor class - ([0846dbb](https://git.0xmax42.io/maxp/http-kernel/commit/0846dbb758ba788f969a381c56498920ee0f9562)) - Add README for HttpKernel project - ([a1ce306](https://git.0xmax42.io/maxp/http-kernel/commit/a1ce30627c68a3f869eb6a104308322af8596dc1)) - Add MIT license file - ([5118a19](https://git.0xmax42.io/maxp/http-kernel/commit/5118a19aeaa1102591aa7fe093fdec1aa19dc7f5)) ### ⚙️ Miscellaneous Tasks +- *(workflows)* Refine branch handling in release process - ([8f94cc9](https://git.0xmax42.io/maxp/http-kernel/commit/8f94cc915c75a11efa1a8e3bdc51ffea9c2f19b5)) - *(workflows)* Update changelog file extension to .md and revert b9d25f23fc - ([a88b4d1](https://git.0xmax42.io/maxp/http-kernel/commit/a88b4d112f5c07664d41f6e9d03246307551f25d)) - Rename changelog and readme files to use .md extension - ([4f2b650](https://git.0xmax42.io/maxp/http-kernel/commit/4f2b65049f461ef377e7231905fd066cbc3c7fe0)) - *(workflows)* Update test workflow for http-kernel project - ([0311546](https://git.0xmax42.io/maxp/http-kernel/commit/03115464e0fb01b8ca00a2fdabde013d004ae8a2)) -- 2.49.1 From d04dfcd63ea2478ffdff2e966d310194dafd8d7d Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 17:25:51 +0200 Subject: [PATCH 07/13] chore(git): ignore merge conflicts for CHANGELOG.md --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..02304b1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +CHANGELOG.md merge=ours -- 2.49.1 From 2ab74b98598ef09370ba31cfbd8e72f2542d6f4f Mon Sep 17 00:00:00 2001 From: ghost-bot Date: Sat, 10 May 2025 15:26:06 +0000 Subject: [PATCH 08/13] chore(changelog): update unreleased changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bffe8ee..8e2bc55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,8 @@ All notable changes to this project will be documented in this file. ### ⚙️ Miscellaneous Tasks -- *(workflows)* Refine branch handling in release process - ([8f94cc9](https://git.0xmax42.io/maxp/http-kernel/commit/8f94cc915c75a11efa1a8e3bdc51ffea9c2f19b5)) +- *(git)* Ignore merge conflicts for CHANGELOG.md - ([6399113](https://git.0xmax42.io/maxp/http-kernel/commit/6399113e122e1207ebf4113aebd250358e31f461)) +- *(workflows)* Refine branch handling in release process - ([71ea424](https://git.0xmax42.io/maxp/http-kernel/commit/71ea4247b35dc4afe5090d3c6502bfa936b5a947)) - *(workflows)* Update changelog file extension to .md and revert b9d25f23fc - ([a88b4d1](https://git.0xmax42.io/maxp/http-kernel/commit/a88b4d112f5c07664d41f6e9d03246307551f25d)) - Rename changelog and readme files to use .md extension - ([4f2b650](https://git.0xmax42.io/maxp/http-kernel/commit/4f2b65049f461ef377e7231905fd066cbc3c7fe0)) - *(workflows)* Update test workflow for http-kernel project - ([0311546](https://git.0xmax42.io/maxp/http-kernel/commit/03115464e0fb01b8ca00a2fdabde013d004ae8a2)) -- 2.49.1 From b69a51247db000214b9218424c72605dde3a0f60 Mon Sep 17 00:00:00 2001 From: ghost-bot Date: Sat, 10 May 2025 15:28:39 +0000 Subject: [PATCH 09/13] chore(changelog): update unreleased changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e2bc55..9096dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,8 +26,8 @@ All notable changes to this project will be documented in this file. ### ⚙️ Miscellaneous Tasks -- *(git)* Ignore merge conflicts for CHANGELOG.md - ([6399113](https://git.0xmax42.io/maxp/http-kernel/commit/6399113e122e1207ebf4113aebd250358e31f461)) -- *(workflows)* Refine branch handling in release process - ([71ea424](https://git.0xmax42.io/maxp/http-kernel/commit/71ea4247b35dc4afe5090d3c6502bfa936b5a947)) +- *(git)* Ignore merge conflicts for CHANGELOG.md - ([d04dfcd](https://git.0xmax42.io/maxp/http-kernel/commit/d04dfcd63ea2478ffdff2e966d310194dafd8d7d)) +- *(workflows)* Refine branch handling in release process - ([8f94cc9](https://git.0xmax42.io/maxp/http-kernel/commit/8f94cc915c75a11efa1a8e3bdc51ffea9c2f19b5)) - *(workflows)* Update changelog file extension to .md and revert b9d25f23fc - ([a88b4d1](https://git.0xmax42.io/maxp/http-kernel/commit/a88b4d112f5c07664d41f6e9d03246307551f25d)) - Rename changelog and readme files to use .md extension - ([4f2b650](https://git.0xmax42.io/maxp/http-kernel/commit/4f2b65049f461ef377e7231905fd066cbc3c7fe0)) - *(workflows)* Update test workflow for http-kernel project - ([0311546](https://git.0xmax42.io/maxp/http-kernel/commit/03115464e0fb01b8ca00a2fdabde013d004ae8a2)) -- 2.49.1 From 2ab6f1b8db2d7bd31ca30248d0de183f17a5738c Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 17:42:19 +0200 Subject: [PATCH 10/13] feat(workflows): conditionally generate changelog - Add logic to generate changelog only if the file exists or on the main branch - Prevent unnecessary changelog generation in other contexts --- .gitea/workflows/release.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 3743270..8f02b21 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -71,8 +71,14 @@ jobs: run: | cargo install git-cliff --version "${{ steps.cliff_version.outputs.version }}" --features gitea - - name: Generate unreleased changelog - run: git-cliff -c cliff.toml -o CHANGELOG.md + - name: Generate unreleased changelog (if file exists or on main) + run: | + if [[ -f CHANGELOG.md || "${GITHUB_REF##refs/heads/}" == "main" ]]; then + echo "Generating CHANGELOG.md..." + git-cliff -c cliff.toml -o CHANGELOG.md + else + echo "CHANGELOG.md does not exist and this is not 'main'. Skipping generation." + fi - name: Commit updated CHANGELOG run: | -- 2.49.1 From 0aac2337a0953368d79be3357489ad0dd405a3b3 Mon Sep 17 00:00:00 2001 From: ghost-bot Date: Sat, 10 May 2025 15:42:59 +0000 Subject: [PATCH 11/13] chore(changelog): update unreleased changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9096dca..d300857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ### 🚀 Features +- *(workflows)* Conditionally generate changelog - ([2ab6f1b](https://git.0xmax42.io/maxp/http-kernel/commit/2ab6f1b8db2d7bd31ca30248d0de183f17a5738c)) - *(interfaces)* Add pipeline executor interface - ([927a908](https://git.0xmax42.io/maxp/http-kernel/commit/927a9081d4f363202520d017eb424c7c097ced94)) - *(pipeline)* Add configuration and hooks for pipeline execution - ([3f114bb](https://git.0xmax42.io/maxp/http-kernel/commit/3f114bb68d94c48a53514752d57cb4f01adeaae3)) - *(workflows)* Add CI for Deno project tests - ([9d5db4f](https://git.0xmax42.io/maxp/http-kernel/commit/9d5db4f414cf961248f2b879f2b132b81a32cb92)) -- 2.49.1 From 6ce73c14fa6736b622e646feb61522e6ec1f4c5a Mon Sep 17 00:00:00 2001 From: "Max P." Date: Sat, 10 May 2025 17:50:05 +0200 Subject: [PATCH 12/13] docs(release): update guidelines for handling changelog - Add instructions to avoid merge conflicts in `CHANGELOG.md` - Provide steps for using `.gitattributes` to automate conflict resolution - Clarify recommended workflows for feature branches and merging --- .gitea/HOWTO_RELEASE.md | 74 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/.gitea/HOWTO_RELEASE.md b/.gitea/HOWTO_RELEASE.md index cb05232..a37855d 100644 --- a/.gitea/HOWTO_RELEASE.md +++ b/.gitea/HOWTO_RELEASE.md @@ -122,3 +122,77 @@ git commit -m "chore(version): bump to 1.2.3" ``` > Nur die ersten beiden erscheinen im Changelog – der dritte wird **automatisch übersprungen**. + +--- + +## 🧾 Umgang mit `CHANGELOG.md` beim Mergen und Releasen + +Wenn du automatisiert einen Changelog mit `git-cliff` erzeugst, ist `CHANGELOG.md` ein **generiertes Artefakt** – und kein handgepflegter Quelltext. + +Beim Mergen von Feature-Branches in `main` kann es deshalb zu **unnötigen Konflikten** in dieser Datei kommen, obwohl der Inhalt später sowieso neu erzeugt wird. + +--- + +## 🧼 Umgang mit `CHANGELOG.md` in Feature-Branches + +Wenn du mit **Feature-Branches** arbeitest, wird `CHANGELOG.md` dort oft automatisch erzeugt. +Das kann beim späteren Merge in `main` zu **unnötigen Merge-Konflikten** führen. + +### ✅ Empfohlene Vorgehensweise + +**Bevor du den Branch mit `main` zusammenführst** (Merge oder Cherry-Pick): + +```bash +git rm CHANGELOG.md +git commit -m "chore(changelog): remove generated CHANGELOG.md before merge" +git push +``` + +Dadurch: + +* verhinderst du Merge-Konflikte mit `CHANGELOG.md` +* wird die Datei bei Feature-Branches nicht mehr automatisch erzeugt +* bleibt deine Historie sauber und konfliktfrei + +> 💡 Der Workflow erzeugt `CHANGELOG.md` automatisch **nur**, wenn: +> +> * die Datei schon vorhanden ist **oder** +> * der Branch `main` heißt + +--- + +## 🧩 Merge-Konflikte verhindern mit `.gitattributes` + +Damit Git bei Konflikten in `CHANGELOG.md` **automatisch deine Version bevorzugt**, kannst du folgende Zeile in die Datei `.gitattributes` aufnehmen: + +```gitattributes +CHANGELOG.md merge=ours +``` + +Das bedeutet: + +* Beim Merge wird die Version aus dem aktuellen Branch (`ours`) behalten +* Änderungen aus dem Ziel-Branch (`theirs`) werden verworfen + +### ✅ So verwendest du es richtig: + +1. **Füge die Regel in `main` hinzu**: + +```bash +echo "CHANGELOG.md merge=ours" >> .gitattributes +git add .gitattributes +git commit -m "chore(git): prevent merge conflicts in CHANGELOG.md" +git push origin main +``` + +2. **Hole sie in deinen Feature-Branch**: + +```bash +git checkout feature/xyz +git rebase origin/main +``` + +3. **Ab sofort werden Konflikte in `CHANGELOG.md` automatisch aufgelöst** – lokal. + +> ⚠️ Hinweis: Plattformen wie **Gitea, GitHub oder GitLab ignorieren `.gitattributes` beim Merge über die Web-Oberfläche**. +> Führe Merges daher **lokal** durch, wenn du Konflikte verhindern willst. -- 2.49.1 From 5d1b0517a5bd6da4a0342fdd15137cdb452d5367 Mon Sep 17 00:00:00 2001 From: ghost-bot Date: Sat, 10 May 2025 15:51:08 +0000 Subject: [PATCH 13/13] chore(changelog): update unreleased changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d300857..8be03b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file. ### 📚 Documentation +- *(release)* Update guidelines for handling changelog - ([6ce73c1](https://git.0xmax42.io/maxp/http-kernel/commit/6ce73c14fa6736b622e646feb61522e6ec1f4c5a)) - *(pipeline)* Add design plan for PipelineExecutor class - ([0846dbb](https://git.0xmax42.io/maxp/http-kernel/commit/0846dbb758ba788f969a381c56498920ee0f9562)) - Add README for HttpKernel project - ([a1ce306](https://git.0xmax42.io/maxp/http-kernel/commit/a1ce30627c68a3f869eb6a104308322af8596dc1)) - Add MIT license file - ([5118a19](https://git.0xmax42.io/maxp/http-kernel/commit/5118a19aeaa1102591aa7fe093fdec1aa19dc7f5)) -- 2.49.1