diff --git a/.github/workflows/publish_dev.yml b/.github/workflows/publish_dev.yml
index 86cb76b6..a717d818 100644
--- a/.github/workflows/publish_dev.yml
+++ b/.github/workflows/publish_dev.yml
@@ -1,8 +1,8 @@
name: Publish Docker Images (dev)
-# Triggers on direct pushes to the 'dev' branch, which includes PR merges.
on:
- push:
+ pull_request_target:
+ types: [ closed ]
branches: [ "dev" ]
env:
@@ -11,41 +11,48 @@ env:
jobs:
bump-version:
name: Bump VERSION file
+ if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write # needed to push the updated VERSION file back
outputs:
new_version: ${{ steps.bump.outputs.version }}
+ version_changed: ${{ steps.bump.outputs.changed }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PIPELINE_PAT }}
+ ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
- name: Detect source branch and bump version
id: bump
run: |
- # ── Detect source branch from merge commit subject ──────────────────
- # Standard merge commit message: "Merge branch 'feature/foo' into dev"
- MERGE_SUBJECT="$(git log --merges -1 --pretty=%s HEAD)"
- echo "Merge subject: ${MERGE_SUBJECT}"
-
- SOURCE=$(echo "$MERGE_SUBJECT" | sed -n "s/Merge branch '\([^']*\)'.*/\1/p")
- SOURCE="${SOURCE#origin/}" # strip remote prefix if present
+ SOURCE="${{ github.event.pull_request.head.ref }}"
if [[ -z "$SOURCE" ]]; then
SOURCE="unknown"
- echo "::warning::Could not detect source branch; defaulting to 'unknown' (no bump)."
+ echo "::warning::Could not detect source branch from pull request metadata; defaulting to 'unknown' (no bump)."
fi
echo "Detected source branch: ${SOURCE}"
# ── Read and parse current VERSION ──────────────────────────────────
RAW="$(cat VERSION | tr -d '[:space:]')"
- CLEAN="${RAW#v}" # strip leading v
- CLEAN="${CLEAN%-dev}" # strip any existing -dev suffix
- IFS='.' read -r MAJOR MINOR PATCH <<< "$CLEAN"
+ CLEAN="${RAW#v}" # strip leading v
+ while [[ "$CLEAN" == *-dev ]]; do
+ CLEAN="${CLEAN%-dev}"
+ done
+
+ if [[ ! "$CLEAN" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
+ echo "::error::VERSION must be in the form v..[-dev], got '${RAW}'"
+ exit 1
+ fi
+
+ MAJOR="${BASH_REMATCH[1]}"
+ MINOR="${BASH_REMATCH[2]}"
+ PATCH="${BASH_REMATCH[3]}"
# ── Apply bump based on branch prefix ────────────────────────────────
PREFIX="${SOURCE%%/*}"
@@ -69,18 +76,29 @@ jobs:
echo "${NEW_VERSION}" > VERSION
echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
+ if [[ "$RAW" != "$NEW_VERSION" ]]; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ fi
echo "New version: ${NEW_VERSION}"
- name: Commit and push updated VERSION
+ if: steps.bump.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add VERSION
+ if git diff --cached --quiet; then
+ echo "No VERSION changes to commit."
+ exit 0
+ fi
git commit -m "chore: bump version to ${{ steps.bump.outputs.version }} [skip ci]"
git push
build-and-push:
name: Build & Push ${{ matrix.container }}
+ if: github.event.pull_request.merged == true
needs: bump-version
runs-on: ubuntu-latest
strategy:
@@ -103,7 +121,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
- ref: dev # pick up the commit that includes the updated VERSION
+ ref: ${{ github.event.pull_request.base.ref }}
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
diff --git a/.github/workflows/publish_main.yml b/.github/workflows/publish_main.yml
index b6be3712..6040a85d 100644
--- a/.github/workflows/publish_main.yml
+++ b/.github/workflows/publish_main.yml
@@ -1,8 +1,8 @@
name: Publish Docker Images (main)
-# Triggers on direct pushes to 'main', which includes PR/merge-commit merges.
on:
- push:
+ pull_request_target:
+ types: [ closed ]
branches: [ "main" ]
env:
@@ -11,41 +11,48 @@ env:
jobs:
bump-version:
name: Bump VERSION file
+ if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write # needed to push back VERSION + Git tag
outputs:
new_version: ${{ steps.bump.outputs.version }}
+ version_changed: ${{ steps.bump.outputs.changed }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PIPELINE_PAT }}
+ ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
- name: Detect source branch and bump version
id: bump
run: |
- # ── Detect source branch from merge commit subject ──────────────────
- # Standard merge commit message: "Merge branch 'feature/foo' into main"
- MERGE_SUBJECT="$(git log --merges -1 --pretty=%s HEAD)"
- echo "Merge subject: ${MERGE_SUBJECT}"
-
- SOURCE=$(echo "$MERGE_SUBJECT" | sed -n "s/Merge branch '\([^']*\)'.*/\1/p")
- SOURCE="${SOURCE#origin/}" # strip remote prefix if present
+ SOURCE="${{ github.event.pull_request.head.ref }}"
if [[ -z "$SOURCE" ]]; then
SOURCE="unknown"
- echo "::warning::Could not detect source branch; defaulting to 'unknown' (no bump)."
+ echo "::warning::Could not detect source branch from pull request metadata; defaulting to 'unknown' (no bump)."
fi
echo "Detected source branch: ${SOURCE}"
# ── Read and parse current VERSION ──────────────────────────────────
RAW="$(cat VERSION | tr -d '[:space:]')"
- CLEAN="${RAW#v}" # strip leading v
- CLEAN="${CLEAN%-dev}" # strip any existing -dev suffix
- IFS='.' read -r MAJOR MINOR PATCH <<< "$CLEAN"
+ CLEAN="${RAW#v}" # strip leading v
+ while [[ "$CLEAN" == *-dev ]]; do
+ CLEAN="${CLEAN%-dev}"
+ done
+
+ if [[ ! "$CLEAN" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
+ echo "::error::VERSION must be in the form v..[-dev], got '${RAW}'"
+ exit 1
+ fi
+
+ MAJOR="${BASH_REMATCH[1]}"
+ MINOR="${BASH_REMATCH[2]}"
+ PATCH="${BASH_REMATCH[3]}"
# ── Decide bump strategy ─────────────────────────────────────────────
# When the source branch is 'dev', the version was already incremented
@@ -74,23 +81,38 @@ jobs:
echo "${NEW_VERSION}" > VERSION
echo "version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
+ if [[ "$RAW" != "$NEW_VERSION" ]]; then
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ fi
echo "New version: ${NEW_VERSION}"
- name: Commit and push updated VERSION
+ if: steps.bump.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add VERSION
+ if git diff --cached --quiet; then
+ echo "No VERSION changes to commit."
+ exit 0
+ fi
git commit -m "chore: release ${{ steps.bump.outputs.version }} [skip ci]"
git push
- name: Create and push Git release tag
run: |
+ if git rev-parse -q --verify "refs/tags/${{ steps.bump.outputs.version }}" >/dev/null 2>&1; then
+ echo "Tag '${{ steps.bump.outputs.version }}' already exists; skipping."
+ exit 0
+ fi
git tag "${{ steps.bump.outputs.version }}"
git push origin "${{ steps.bump.outputs.version }}"
build-and-push:
name: Build & Push ${{ matrix.container }}
+ if: github.event.pull_request.merged == true
needs: bump-version
runs-on: ubuntu-latest
strategy:
@@ -113,7 +135,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
with:
- ref: main # pick up the commit that includes the updated VERSION
+ ref: ${{ github.event.pull_request.base.ref }}
- name: Derive partial version tags
id: version
diff --git a/README.md b/README.md
index c246509c..cdb9c8a8 100644
--- a/README.md
+++ b/README.md
@@ -43,16 +43,13 @@
-
-
-
## About the Project
-
+
## Getting Started
@@ -60,16 +57,15 @@
```sh
HOST_IP=127.0.0.1 docker compose -f docker/docker-compose.yml --profile prod up
```
-
-
-
-
#### Use the dev profile for testing out changes in docker containers:
```sh
HOST_IP=127.0.0.1 docker compose -f docker/docker-compose.yml --profile dev up
```
+
@@ -85,7 +81,7 @@ possibly infrastructure.
The section `pipeline.log_collection.collector.logline_format` has to be adjusted to reflect your specific input log
line format. Using our adjustable and flexible log line configuration, you can rename, reorder and fully configure each
-field of a valid log line. Freely define timestamps, RegEx patterns, lists, and IP addresses. For example, your
+field of a valid log line. You can freely define timestamps, RegEx patterns, lists, and IP addresses. For example, your
configuration might look as follows:
```yml
@@ -187,24 +183,11 @@ Have a look at the following pictures showing examples of how these dashboards m
-
-
-
## Models and Training
-To train and test our and possibly your own models, we currently rely on the following datasets:
-
-- [DGTA Benchmark](https://data.mendeley.com/datasets/2wzf9bz7xr/1)
-- [DNS Tunneling Queries for Binary Classification](https://data.mendeley.com/datasets/mzn9hvdcxg/1)
-- [UMUDGA - University of Murcia Domain Generation Algorithm Dataset](https://data.mendeley.com/datasets/y8ph45msv8/1)
-- [DGArchive](https://dgarchive.caad.fkie.fraunhofer.de/)
-- [DNS Exfiltration](https://data.mendeley.com/datasets/c4n7fckkz3/3)
-
-We compute all features separately and only rely on the `domain` and `class` for binary classification.
-
### Inserting Data for Testing
-For testing purposes, you can ingest PCAPs or tap on network interfaces using the zeek-based sensor in its `1.0.0` release. For more information on it, please refer to [the documentation](https://github.com/Hamstring-NDR/hamstring-zeek).
+For testing purposes, you can ingest PCAPs or tap on network interfaces using the zeek-based sensor that is integrated into the docker-compose file. For more information on the sensor, please refer to [the documentation](https://github.com/Hamstring-NDR/hamstring-zeek).
### Training Your Own Models
@@ -260,33 +243,6 @@ The results will be saved per default to `./results`, if not configured otherwis
```
This will create a `rules.txt` file containing the innards of the model, explaining the rules it created.
-
-
-
-### Data
-
-> [!IMPORTANT]
-> We support custom schemes.
-
-Depending on your data and usecase, you can customize the data scheme to fit your needs.
-The below configuration is part of the [main configuration file](./config.yaml) which is detailed in our [documentation](https://HAMSTRING.readthedocs.io/en/latest/usage.html#id2)
-
-```yml
-loglines:
- fields:
- - [ "timestamp", RegEx, '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$' ]
- - [ "status_code", ListItem, [ "NOERROR", "NXDOMAIN" ], [ "NXDOMAIN" ] ]
- - [ "src_ip", IpAddress ]
- - [ "dns_server_ip", IpAddress ]
- - [ "domain_name", RegEx, '^(?=.{1,253}$)((?!-)[A-Za-z0-9-]{1,63}(?(back to top)
## Contributing
@@ -305,16 +261,12 @@ Don't forget to give the project a star! Thanks again!
-