Skip to content

Commit 00103bb

Browse files
committed
v1.0-RC readiness
1 parent e27b6f3 commit 00103bb

52 files changed

Lines changed: 11941 additions & 1053 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,28 @@ name: CI
33
on:
44
push:
55
branches: [ main, mvp-0.0.1-snapshot ]
6+
paths:
7+
- 'modules/**'
8+
- 'build.sbt'
9+
- 'project/**'
10+
- '.github/workflows/ci.yml'
11+
- '!docs/**'
12+
- '!**/*.md'
613
pull_request:
714
branches: [ main, mvp-0.0.1-snapshot ]
15+
paths:
16+
- 'modules/**'
17+
- 'build.sbt'
18+
- 'project/**'
19+
- '.github/workflows/ci.yml'
20+
workflow_dispatch:
21+
22+
permissions:
23+
contents: read
24+
25+
concurrency:
26+
group: ${{ github.workflow }}-${{ github.ref }}
27+
cancel-in-progress: true
828

929
env:
1030
JAVA_OPTS: -Xmx4G -XX:+UseG1GC
@@ -39,52 +59,34 @@ jobs:
3959
modules/engines-flink/target
4060
name: ${{ matrix.module }}
4161
runs-on: ubuntu-22.04
62+
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
4263
steps:
4364
- name: Checkout
4465
uses: actions/checkout@v4
4566

46-
- name: Set up JDK 21
67+
- name: Set up JDK 17 (with SBT cache)
4768
uses: actions/setup-java@v4
4869
with:
4970
distribution: temurin
50-
java-version: '21'
51-
52-
- name: Cache SBT and dependencies
53-
uses: actions/cache@v4
54-
with:
55-
path: |
56-
~/.ivy2/cache
57-
~/.cache/coursier
58-
~/.sbt
59-
${{ matrix.paths }}
60-
key: ${{ runner.os }}-sbt-${{ matrix.module }}-${{ hashFiles('**/build.sbt', '**/project/**/*.sbt', format('modules/{0}/**', matrix.module)) }}
61-
restore-keys: |
62-
${{ runner.os }}-sbt-${{ matrix.module }}-
71+
java-version: '17'
72+
cache: 'sbt'
6373

6474
- name: Build module
6575
run: sbt -batch ${{ matrix.commands }}
6676

6777
refactor-lint:
6878
name: Refactor lint & Unsafe cast gate
6979
runs-on: ubuntu-22.04
80+
if: ${{ !github.event.pull_request.draft }}
7081
steps:
7182
- name: Checkout
7283
uses: actions/checkout@v4
73-
- name: Set up JDK 21
84+
- name: Set up JDK 17 (with SBT cache)
7485
uses: actions/setup-java@v4
7586
with:
7687
distribution: temurin
77-
java-version: '21'
78-
- name: Cache Ivy and Coursier
79-
uses: actions/cache@v4
80-
with:
81-
path: |
82-
~/.ivy2/cache
83-
~/.cache/coursier
84-
~/.sbt
85-
key: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt', '**/project/**/*.sbt', '**/.scalafix.conf') }}
86-
restore-keys: |
87-
${{ runner.os }}-sbt-
88+
java-version: '17'
89+
cache: 'sbt'
8890
- name: Scalafix check (no rewrites)
8991
continue-on-error: true
9092
run: sbt -batch "scalafixAll --check"
@@ -97,7 +99,7 @@ jobs:
9799
# Whitelist files where reflective casts are intentionally localized
98100
WHITELIST=(
99101
"modules/engines-spark/src/main/scala/com/flowforge/engines/spark/SparkDataAlgebra.scala"
100-
"modules/core/src/main/scala/com/flowforge/core/contracts/internal/SchemaConformsMacros.scala"
102+
"modules/core/src/main/scala/com/flowforge/core/contracts/internal/ContractMacros.scala"
101103
)
102104
103105
is_whitelisted() {
@@ -127,6 +129,61 @@ jobs:
127129
fi
128130
echo "✅ PASS: No unsafe asInstanceOf/Any found outside whitelist"
129131
132+
doc-lint:
133+
name: Scaladoc coverage (report → enforce later)
134+
runs-on: ubuntu-22.04
135+
steps:
136+
- name: Checkout
137+
uses: actions/checkout@v4
138+
- name: Install ripgrep
139+
run: sudo apt-get update && sudo apt-get install -y ripgrep
140+
- name: Scan public packages for missing Scaladoc
141+
shell: bash
142+
run: |
143+
set -euo pipefail
144+
ROOTS=(
145+
modules/core/src/main/scala/com/flowforge/core
146+
modules/core/src/main/scala/com/flowforge/framework
147+
modules/core/src/main/scala/com/flowforge/core/contracts
148+
modules/core/src/main/scala/com/flowforge/core/algebra
149+
modules/engines-spark/src/main/scala/com/flowforge/engines/spark
150+
modules/quality-deequ/src/main/scala/com/flowforge/quality/deequ
151+
)
152+
total=0; missing=0
153+
mapfile -t FILES < <(rg -l "^" "${ROOTS[@]}" --glob "**/*.scala" || true)
154+
offenders=()
155+
for file in "${FILES[@]}"; do
156+
# Classes/traits/objects
157+
while IFS= read -r line; do
158+
ln=${line%%:*}; decl=${line#*:*:}
159+
(( total++ ))
160+
start=$((ln-3)); [ $start -lt 1 ] && start=1
161+
if ! sed -n "$start,$((ln-1))p" "$file" | rg -q "^/\*\*"; then
162+
offenders+=("$file:$ln:$decl")
163+
(( missing++ ))
164+
fi
165+
done < <(rg -n "^\s*(final\s+)?(case\s+)?(class|trait|object)\s+\w+" "$file" || true)
166+
# Public defs (basic heuristic)
167+
while IFS= read -r line; do
168+
ln=${line%%:*}; decl=${line#*:*:}
169+
(( total++ ))
170+
start=$((ln-3)); [ $start -lt 1 ] && start=1
171+
if ! sed -n "$start,$((ln-1))p" "$file" | rg -q "^/\*\*"; then
172+
offenders+=("$file:$ln:$decl")
173+
(( missing++ ))
174+
fi
175+
done < <(rg -n "^\s*def\s+\w+\s*\(" "$file" | rg -v "^\s*(private|protected)\b" || true)
176+
done
177+
cov=$(( ( (total-missing) * 100 ) / ( (total==0) ? 1 : total ) ))
178+
echo "Scaladoc coverage: $cov% ($((total-missing))/$total)"
179+
if [ ${#offenders[@]} -gt 0 ]; then
180+
echo "First 200 missing docs:"; printf '%s\n' "${offenders[@]}" | head -n 200
181+
fi
182+
# ENFORCE: fail when offenders exist (single CI run post-sweep)
183+
if [ ${#offenders[@]} -gt 0 ]; then
184+
echo "❌ Missing Scaladoc found"; exit 1
185+
fi
186+
130187
- name: Try/Try-catch/unsafeRunSync bans (main sources only)
131188
shell: bash
132189
run: |

.github/workflows/release.yml

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ on:
1616
default: false
1717
type: boolean
1818

19+
permissions:
20+
contents: write
21+
pages: write
22+
id-token: write
23+
1924
concurrency:
2025
group: release-${{ github.ref }}
2126
cancel-in-progress: false
@@ -82,11 +87,11 @@ jobs:
8287
- name: Checkout
8388
uses: actions/checkout@v4
8489

85-
- name: Setup Java 21
90+
- name: Setup Java 17
8691
uses: actions/setup-java@v4
8792
with:
8893
distribution: 'temurin'
89-
java-version: '21'
94+
java-version: '17'
9095

9196
- name: Cache SBT and dependencies
9297
uses: actions/cache@v4
@@ -148,11 +153,11 @@ jobs:
148153
- name: Checkout
149154
uses: actions/checkout@v4
150155

151-
- name: Setup Java 21
156+
- name: Setup Java 17
152157
uses: actions/setup-java@v4
153158
with:
154159
distribution: 'temurin'
155-
java-version: '21'
160+
java-version: '17'
156161

157162
- name: Cache SBT and dependencies
158163
uses: actions/cache@v4
@@ -193,9 +198,83 @@ jobs:
193198
path: release-artifacts/
194199
retention-days: 30
195200

201+
publish-docs:
202+
name: Publish Scaladoc to GitHub Pages
203+
needs: [validate-release, pre-release-tests]
204+
runs-on: ubuntu-latest
205+
environment:
206+
name: github-pages
207+
url: ${{ steps.deployment.outputs.page_url }}
208+
steps:
209+
- name: Checkout
210+
uses: actions/checkout@v4
211+
with:
212+
fetch-depth: 0
213+
- name: Setup Java 17
214+
uses: actions/setup-java@v4
215+
with:
216+
distribution: 'temurin'
217+
java-version: '17'
218+
- name: Cache SBT and dependencies
219+
uses: actions/cache@v4
220+
with:
221+
path: |
222+
~/.sbt
223+
~/.coursier/cache
224+
~/.ivy2/cache
225+
key: ${{ runner.os }}-sbt-docs-${{ hashFiles('**/*.sbt', '**/project/**/*.scala') }}
226+
restore-keys: |
227+
${{ runner.os }}-sbt-docs-
228+
${{ runner.os }}-sbt-
229+
- name: Generate Scaladoc for all modules
230+
run: |
231+
sbt -batch doc
232+
# Try unified docs for Scala 2.13 modules; don't fail release if unidoc fails
233+
sbt -batch unidoc || echo "unidoc failed (non-fatal)"
234+
- name: Assemble site folder
235+
run: |
236+
mkdir -p public/api
237+
for m in modules/*; do \
238+
mod=$(basename "$m"); \
239+
api_dir="$m/target/scala-2.13/api"; \
240+
if [ -d "$api_dir" ]; then \
241+
mkdir -p "public/api/$mod"; \
242+
cp -R "$api_dir"/* "public/api/$mod"/; \
243+
fi; \
244+
done
245+
# Root module (if any aggregated docs exist)
246+
if [ -d target/scala-2.13/api ]; then \
247+
mkdir -p public/api/root && cp -R target/scala-2.13/api/* public/api/root/; \
248+
fi
249+
# Unified docs (if present)
250+
if [ -d target/scala-2.13/unidoc ] || [ -d target/scala-2.13/api-unidoc ]; then \
251+
UNIDOC_DIR="$(ls -d target/scala-2.13/*unidoc 2>/dev/null | head -n1)"; \
252+
if [ -n "$UNIDOC_DIR" ]; then \
253+
mkdir -p public/api/unified && cp -R "$UNIDOC_DIR"/* public/api/unified/; \
254+
fi; \
255+
fi
256+
# Add index
257+
cat > public/index.html << 'EOF'
258+
<!doctype html>
259+
<html><head><meta charset="utf-8"><title>FlowForge API</title></head>
260+
<body>
261+
<h1>FlowForge API (Scaladoc)</h1>
262+
<ul>
263+
$(for d in api/*; do echo "<li><a href=\"$d/index.html\">$(basename "$d")</a></li>"; done)
264+
</ul>
265+
</body></html>
266+
EOF
267+
- name: Upload Pages artifact
268+
uses: actions/upload-pages-artifact@v3
269+
with:
270+
path: public
271+
- name: Deploy to GitHub Pages
272+
id: deployment
273+
uses: actions/deploy-pages@v4
274+
196275
create-release:
197276
name: Create GitHub Release
198-
needs: [validate-release, pre-release-tests, build-artifacts]
277+
needs: [validate-release, pre-release-tests, build-artifacts, publish-docs]
199278
runs-on: ubuntu-latest
200279
steps:
201280
- name: Checkout

0 commit comments

Comments
 (0)