Skip to content

Commit dce2c93

Browse files
authored
ci: add CI, release, security workflows and VERSION file (#2)
1 parent 1246555 commit dce2c93

9 files changed

Lines changed: 213 additions & 51 deletions

File tree

.github/labeler.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# .github/labeler.yml — path-based PR auto-labels (actions/labeler@v5 format).
2+
documentation:
3+
- changed-files:
4+
- any-glob-to-any-file: ["**/*.md", "docs/**"]
5+
ci:
6+
- changed-files:
7+
- any-glob-to-any-file: [".github/**"]
8+
dependencies:
9+
- changed-files:
10+
- any-glob-to-any-file:
11+
["**/package.json", "**/pubspec.yaml", "**/go.mod", "**/*.lock", "**/*lock.yaml"]
12+
tests:
13+
- changed-files:
14+
- any-glob-to-any-file: ["**/*.test.*", "**/*_test.*", "test/**", "**/__tests__/**"]

.github/workflows/ci.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["master"]
6+
pull_request:
7+
branches: ["master"]
8+
9+
permissions:
10+
contents: read
11+
12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build:
18+
name: build
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v6
22+
with:
23+
persist-credentials: false
24+
- name: Configure
25+
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
26+
- name: Build
27+
run: cmake --build build --config Release
28+
- name: Test
29+
run: |
30+
if [ -f build/CTestTestfile.cmake ]; then ctest --test-dir build --output-on-failure; \
31+
else echo "no ctest targets — skipping"; fi

.github/workflows/codeql.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

.github/workflows/labeler.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Labeler
2+
3+
# Auto-labels PRs by the paths they touch (config in .github/labeler.yml).
4+
on:
5+
pull_request_target:
6+
types: [opened, synchronize, reopened]
7+
8+
permissions:
9+
contents: read
10+
pull-requests: write
11+
12+
jobs:
13+
label:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/labeler@v5
17+
with:
18+
sync-labels: true

.github/workflows/release.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Release
2+
3+
# On push to the default branch (a merged PR), tag v<VERSION> and create a
4+
# GitHub Release with generated notes — unless the tag already exists. For repos
5+
# with no package manifest (C++, Shell). For Go (siphon) the existing GoReleaser
6+
# workflow is itself triggered by this tag and builds the binaries.
7+
on:
8+
push:
9+
branches: ["master"]
10+
workflow_dispatch: {}
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
release:
17+
name: Tag and release
18+
runs-on: ubuntu-latest
19+
permissions:
20+
contents: write
21+
steps:
22+
- uses: actions/checkout@v6
23+
with:
24+
fetch-depth: 0
25+
persist-credentials: false
26+
- name: Read version
27+
id: v
28+
run: echo "tag=v$(tr -d ' \r\n' < VERSION)" >> "$GITHUB_OUTPUT"
29+
- name: Release if new
30+
env:
31+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
TAG: ${{ steps.v.outputs.tag }}
33+
run: |
34+
if gh release view "$TAG" >/dev/null 2>&1 \
35+
|| git ls-remote --tags origin "refs/tags/$TAG" | grep -q .; then
36+
echo "Tag $TAG already exists — skipping."; exit 0
37+
fi
38+
gh release create "$TAG" --target "${{ github.sha }}" --title "$TAG" --generate-notes
39+
echo "Released $TAG ✓"

.github/workflows/scorecard.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Scorecard
2+
3+
# OpenSSF Scorecard — supply-chain security posture. Runs on push to the default
4+
# branch and weekly; uploads SARIF so findings show in the Security tab.
5+
on:
6+
push:
7+
branches: ["master"]
8+
schedule:
9+
- cron: "27 3 * * 1" # Mondays 03:27 UTC
10+
workflow_dispatch: {}
11+
12+
permissions: read-all
13+
14+
jobs:
15+
analysis:
16+
name: Scorecard analysis
17+
runs-on: ubuntu-latest
18+
permissions:
19+
security-events: write # upload SARIF to code scanning
20+
id-token: write # publish results to the OpenSSF API
21+
steps:
22+
- uses: actions/checkout@v6
23+
with:
24+
persist-credentials: false
25+
- uses: ossf/scorecard-action@v2.4.0
26+
with:
27+
results_file: results.sarif
28+
results_format: sarif
29+
publish_results: true
30+
- uses: github/codeql-action/upload-sarif@v3
31+
with:
32+
sarif_file: results.sarif

.github/workflows/stale.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Stale
2+
3+
# Marks inactive issues/PRs stale, then closes them after a grace period.
4+
on:
5+
schedule:
6+
- cron: "0 4 * * *" # daily 04:00 UTC
7+
workflow_dispatch: {}
8+
9+
permissions:
10+
issues: write
11+
pull-requests: write
12+
13+
jobs:
14+
stale:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/stale@v9
18+
with:
19+
days-before-stale: 60
20+
days-before-close: 14
21+
stale-issue-label: stale
22+
stale-pr-label: stale
23+
exempt-issue-labels: pinned,security,blocked
24+
exempt-pr-labels: pinned,security,blocked
25+
stale-issue-message: >
26+
This issue has been inactive for 60 days and is now marked stale.
27+
Comment to keep it open; it will close in 14 days otherwise.
28+
stale-pr-message: >
29+
This PR has been inactive for 60 days and is now marked stale.
30+
Push or comment to keep it open; it will close in 14 days otherwise.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Version Check
2+
3+
# Every PR must bump the root VERSION file (plain "x.y.z"). Release tags it on
4+
# merge. Used by repos with no package manifest (Go, C++, Shell).
5+
on:
6+
pull_request:
7+
branches: ["master"]
8+
types: [opened, synchronize, reopened]
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
version-bumped:
15+
name: version bumped
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v6
19+
with:
20+
fetch-depth: 0 # need the base branch to diff the version
21+
persist-credentials: false
22+
- name: Read versions
23+
id: v
24+
run: |
25+
git fetch --no-tags --depth=1 origin "${{ github.base_ref }}"
26+
pr=$(tr -d ' \r\n' < VERSION)
27+
# If VERSION doesn't exist on the base yet (the PR that introduces it),
28+
# treat the base as 0.0.0 so any real version passes the bump check.
29+
base=$(git show "origin/${{ github.base_ref }}:VERSION" 2>/dev/null | tr -d ' \r\n' || true)
30+
base=${base:-0.0.0}
31+
echo "pr=$pr" >> "$GITHUB_OUTPUT"
32+
echo "base=$base" >> "$GITHUB_OUTPUT"
33+
- name: Compare
34+
env:
35+
PR: ${{ steps.v.outputs.pr }}
36+
BASE: ${{ steps.v.outputs.base }}
37+
run: |
38+
echo "base=$BASE pr=$PR"
39+
if [ "$PR" = "$BASE" ]; then
40+
echo "::error::VERSION not bumped (still $BASE)."
41+
exit 1
42+
fi
43+
greater=$(printf '%s\n%s\n' "$BASE" "$PR" | sort -V | tail -n1)
44+
if [ "$greater" != "$PR" ]; then
45+
echo "::error::VERSION $PR is lower than base $BASE."
46+
exit 1
47+
fi
48+
echo "Version bumped $BASE -> $PR ✓"

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.0.0

0 commit comments

Comments
 (0)