Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Code owners for files that can alter the release pipeline or execute code
# while release/publication credentials are present.
#
# IMPORTANT: CODEOWNERS has no effect unless the 'main' branch ruleset requires
# a pull request with "Require review from Code Owners" enabled. As a solo
# maintainer you cannot approve your own PRs, so enable code-owner review only
# once the project has a second trusted maintainer. Until then this file still
# documents ownership and triggers review requests. See docs/release-security.md.

# CI/CD workflows, this file, and repository automation
/.github/ @ivangsa

# Gradle build definitions: plugins and build logic declared here execute
# during release builds and snapshot publication.
/build.gradle.kts @ivangsa
/settings.gradle.kts @ivangsa
/gradle/ @ivangsa
/gradlew @ivangsa
/gradlew.bat @ivangsa

# Kotlin/JS toolchain lockfile (yarn.lock) used by the Gradle build.
/kotlin-js-store/ @ivangsa

# npm code executed during builds (Node.js integration tests).
/nodejs-test-project/ @ivangsa

# Release notes consumed verbatim by the release workflow.
/release-notes/ @ivangsa

# Release documentation.
/docs/release-security.md @ivangsa
/RELEASING.md @ivangsa
17 changes: 0 additions & 17 deletions .github/dependabot..yml

This file was deleted.

21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Dependabot keeps release-relevant dependencies current:
# - github-actions: bumps the full-SHA pins in .github/workflows (supply-chain
# control -- pinned actions only move via a reviewable PR).
# - gradle: dependency/plugin updates against the working branch 'develop'.
# - npm: Node.js integration-test project dependencies.
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "gradle"
directory: "/"
target-branch: "develop"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/nodejs-test-project"
target-branch: "develop"
schedule:
interval: "weekly"
90 changes: 0 additions & 90 deletions .github/workflows/prepare-maven-release.yml

This file was deleted.

63 changes: 0 additions & 63 deletions .github/workflows/publish-maven-central.yml

This file was deleted.

74 changes: 54 additions & 20 deletions .github/workflows/publish-maven-snapshots.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,74 @@
name: Build and Publish Snapshots

# Security model: see docs/release-security.md#snapshot-publication
#
# Snapshot publication triggers only from the protected internal branches
# 'develop' and 'next' (push, or explicit dispatch from those branches).
# Secrets live in the 'maven-central-snapshots' GitHub Environment whose
# deployment branch policy is restricted to develop/next, so a dispatch from
# any other branch cannot obtain them even with a modified workflow file.
#
# Residual risk (documented): any code merged into develop/next executes via
# `./gradlew publishToMavenCentral` while the snapshot publishing credentials
# are present.
on:
push:
branches: [ develop, next ]
branches: [develop, next]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: maven-snapshots-${{ github.ref }}
cancel-in-progress: false

jobs:
build:
publish-snapshot:
name: Build, test and publish snapshot
runs-on: ubuntu-latest

timeout-minutes: 60
# Defense in depth; the environment branch policy is the hard boundary.
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/next'
environment: maven-central-snapshots
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

# The committed gradle-wrapper.jar is executable code: verify its
# checksum against Gradle's published checksums before running it.
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@748248ddd2a24f49513d8f472f81c3a07d4d50e1 # v4.4.4

- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
java-version: "17"
distribution: "temurin"
cache: "gradle"

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '18'
node-version: "18"

- name: Grant execute permission for gradlew
run: chmod +x gradlew
# Guard against accidentally publishing a release version as a snapshot.
# Runs without secrets in the environment.
- name: Enforce snapshot version
run: |
set -euo pipefail
if ! grep -qE '^version = "[0-9]+\.[0-9]+\.[0-9]+-SNAPSHOT"$' build.gradle.kts; then
echo "::error::build.gradle.kts version is not a -SNAPSHOT; refusing to publish a snapshot."
grep '^version = ' build.gradle.kts || true
exit 1
fi

- name: Build and test with coverage
run: ./gradlew build koverHtmlReport koverXmlReport koverLog
run: |
chmod +x gradlew
./gradlew build koverHtmlReport koverXmlReport koverLog

- name: Extract coverage metrics
if: always()
Expand Down Expand Up @@ -62,12 +98,6 @@ jobs:
env.write(f"BRANCH_COVERAGE={metrics.get('BRANCH', 0)}\n")
PY

- name: Print coverage to console
if: always()
run: |
echo "line coverage = ${LINE_COVERAGE}%"
echo "branch coverage = ${BRANCH_COVERAGE}%"

- name: Publish coverage summary
if: always()
run: |
Expand All @@ -80,14 +110,18 @@ jobs:
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload coverage reports
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: coverage-reports
path: |
build/reports/kover/
build/reports/tests/

# Secrets are scoped to this single step. Everything Gradle runs here
# (plugins, dependencies, Kotlin/JS tooling) executes with the snapshot
# credentials present -- that is the documented residual risk of
# snapshot publishing.
- name: Publish snapshots to Maven Central
run: ./gradlew publishToMavenCentral
env:
Expand Down
Loading
Loading