Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
f5c4b3e
docs: add hardware meter integration guide (#320)
devnWisdom May 29, 2026
b0bdc8d
devops: configure Dependabot for npm, Cargo, and GitHub Actions (#306)
devnWisdom May 29, 2026
cabf63b
devops: add resource limits to Docker Compose services (#304)
devnWisdom May 29, 2026
2638a9f
docs: add operational runbooks (#315)
devnWisdom May 29, 2026
9385ff4
feat: enable Turborepo remote caching for all CI steps (#297)
devUnixx May 29, 2026
60bfed0
test: add contract event emission tests for all state-changing functi…
devUnixx May 29, 2026
3ee0154
feat: configure log aggregation and retention (#299)
devEunicee May 29, 2026
06fc257
Merge branch 'main' into feat/299-log-aggregation
AnnabelJoe May 29, 2026
5d85f7b
Merge pull request #397 from devEunicee/feat/299-log-aggregation
AnnabelJoe May 29, 2026
4781be5
chore(release): 1.9.0 [skip ci]
semantic-release-bot May 29, 2026
4def0e7
feat(contracts): optimize Soroban storage for audit-registry
becckyrebecca May 30, 2026
a6b4365
test(contracts): rename regression test for issue #281
becckyrebecca May 30, 2026
cd9a68c
docs(docs): write governance parameter tuning guide
becckyrebecca May 30, 2026
f9055f7
feat(contracts): optimize Soroban storage for audit-registry
becckyrebecca May 30, 2026
b9e0b98
feat: implement rate limiting on /api/readings #266
Gina-georgina May 30, 2026
249dd4f
feat: add dark mode toggle to settings and enhance theme support #253
Gina-georgina May 30, 2026
cc85f83
feat: implement global and section error boundaries #256
Gina-georgina May 30, 2026
4d2bde0
feat: add pagination and filtering to certificates #258
Gina-georgina May 30, 2026
9d5e48b
Merge branch 'main' into issue-258-pagination
AnnabelJoe May 30, 2026
61bdc24
Merge pull request #408 from Gina-georgina/issue-258-pagination
AnnabelJoe May 30, 2026
b0ac31b
chore(release): 1.10.0 [skip ci]
semantic-release-bot May 30, 2026
4cc1fbf
Merge branch 'main' into issue-256-error-boundaries
AnnabelJoe May 30, 2026
801a616
Merge pull request #407 from Gina-georgina/issue-256-error-boundaries
AnnabelJoe May 30, 2026
f4a94b2
chore(release): 1.11.0 [skip ci]
semantic-release-bot May 30, 2026
219aae9
Merge branch 'main' into issue-253-dark-mode
AnnabelJoe May 30, 2026
dee7a67
Merge pull request #406 from Gina-georgina/issue-253-dark-mode
AnnabelJoe May 30, 2026
4677309
chore(release): 1.12.0 [skip ci]
semantic-release-bot May 30, 2026
54007c7
Merge branch 'main' into issue-266-rate-limiting
AnnabelJoe May 30, 2026
c7e9d87
Merge pull request #405 from Gina-georgina/issue-266-rate-limiting
AnnabelJoe May 30, 2026
580a52c
chore(release): 1.13.0 [skip ci]
semantic-release-bot May 30, 2026
c4ca766
Merge pull request #404 from becckyrebecca/feat/retire-function-279
AnnabelJoe May 30, 2026
1b86929
chore(release): 1.14.0 [skip ci]
semantic-release-bot May 30, 2026
df228e5
Merge pull request #403 from becckyrebecca/feat/optimize-soroban-stor…
AnnabelJoe May 30, 2026
52e376c
chore(release): 1.15.0 [skip ci]
semantic-release-bot May 30, 2026
8281f08
docs: standardize CHANGELOG.md and update PR template #312
becckyrebecca May 30, 2026
88e03de
security: add dependency scanning to CI and auto-issue creation #293
becckyrebecca May 30, 2026
3ee2c87
Merge pull request #410 from becckyrebecca/feat/dependency-audit-293
AnnabelJoe May 30, 2026
aa3eeaf
Merge branch 'main' into feat/changelog-312
AnnabelJoe May 30, 2026
93a2667
Merge pull request #409 from becckyrebecca/feat/changelog-312
AnnabelJoe May 30, 2026
7698660
docs: create SECURITY.md with vulnerability disclosure policy (#314)
ZainabJanee May 30, 2026
ce744ea
ops: configure Redis persistence and eviction policy (#294)
ZainabJanee May 30, 2026
ce90af9
feat: implement meter key revocation mechanism (#339)
ZainabJanee May 30, 2026
3691090
test: add snapshot tests for React components and fix Navbar (#328)
ZainabJanee May 30, 2026
3de6ce8
Merge pull request #414 from ZainabJanee/test/328-snapshot-tests
AnnabelJoe May 30, 2026
79f5662
feat(contracts): add upgrade timelock tests for community_governance …
pauljacobb May 31, 2026
7881a7e
feat(web): real-time energy chart with WebSocket + polling fallback (…
pauljacobb May 31, 2026
18c472a
docs(contracts): add/enhance Rust doc comments on all public function…
pauljacobb May 31, 2026
e90113d
test(web): add API route tests and enforce 80% coverage threshold (#325)
pauljacobb May 31, 2026
eb1a425
docs: add user guide for web dashboard (closes #317)
Magada06 May 31, 2026
9b2ce49
feat(security): add RLS policies for multi-tenant isolation (#274)
Magada06 May 31, 2026
3fc2fcd
feat: add loading skeletons for async data fetches (#255)
Magada06 May 31, 2026
b1d6e5f
ci: add dedicated Contracts CI workflow (#287)
Philzwrist07 May 31, 2026
120d730
docs: add Stellar mainnet deployment checklist and go-live plan
Philzwrist07 May 31, 2026
29135d5
feat(testing): add mutation testing for Rust contracts and TS utiliti…
Philzwrist07 May 31, 2026
861bcce
feat: implement certificate retirement API endpoint (#270)
devAgatha Jun 1, 2026
ecda905
feat(governance): configurable quorum/threshold with admin guard and …
jhayniffy Jun 1, 2026
2b79205
feat(crypto): add verifyReadingSignature and 100% unit test coverage
jhayniffy Jun 1, 2026
fa8bf84
feat(api): versioning — 301 redirects from /api/* to /api/v1/*, API-V…
jhayniffy Jun 1, 2026
164dbc7
feat(ci): Docker image scanning with Trivy — block on CRITICAL CVEs
jhayniffy Jun 1, 2026
7e37584
feat(db): add perf indexes on readings, certificates, audit_anchors
jhayniffy Jun 1, 2026
5ae1a9e
ci: automate Vercel production deploy gated on CI
jhayniffy Jun 1, 2026
a1ec4b7
fix: resolve JSX parse errors in dashboard and verify pages
jhayniffy Jun 1, 2026
515ed8d
feat(governance): add proposed_action field to create proposal form
jhayniffy Jun 1, 2026
1d6db6b
fix(security): add security headers to all HTTP responses (#340)
JosephOnuh Jun 1, 2026
2834203
fix(security): implement CSP headers for Next.js web app (#333)
JosephOnuh Jun 1, 2026
ab4b39e
fix(ci): add dependency license compliance check (#344)
JosephOnuh Jun 1, 2026
34d0971
fix(security): implement audit logging for sensitive operations (#341)
JosephOnuh Jun 1, 2026
477a577
feat: certificate transfer endpoint and UI (#1)
jhayniffy Jun 1, 2026
325b565
feat: mock Freighter wallet for CI testing (#2)
jhayniffy Jun 1, 2026
0d90853
test: tracer-sim integration tests (#3)
jhayniffy Jun 1, 2026
232bf4a
feat: I-REC XML export for certificates (#4)
jhayniffy Jun 1, 2026
1ecf24e
feat(e2e): add Playwright tests for dashboard, certificate detail, an…
jhayniffy Jun 1, 2026
d4117a7
feat(auth): configure token expiry, rotation, and revocation list
jhayniffy Jun 1, 2026
45c9c81
feat(security): HTTPS redirect and HSTS headers
jhayniffy Jun 1, 2026
71dc4a9
feat: add public v1 verify API and OpenAPI spec (#352)
Sammy-Samy Jun 1, 2026
d27703e
feat: add pentest scope and report placeholder (#342)
Sammy-Samy Jun 1, 2026
196ab0c
feat: add bulk certificate retirement API and UI (#347)
Sammy-Samy Jun 1, 2026
4205191
feat: implement webhook notifications for certificate lifecycle event…
Sammy-Samy Jun 1, 2026
84ee9a6
feat: support fractional kWh tokens with 3 decimal places
Dev-Odun-oss Jun 1, 2026
d5416fd
fix issue 137 & 138
Benalex8797 Jun 1, 2026
49bd5fe
feat: admin interface and fractional kWh support
doradenise-jpg Jun 1, 2026
944c5b9
feat(security): add HTTP security headers (#129)
woodlonestar-lang Jun 2, 2026
a437a9b
feat(security): API key auth for meter submissions (#131)
woodlonestar-lang Jun 2, 2026
037e825
feat(security): restrict Supabase service role key usage (#134)
woodlonestar-lang Jun 2, 2026
7ce4a12
feat(notifications): email alerts for mint, retire, and mint failure …
woodlonestar-lang Jun 2, 2026
cb1f85b
update
confima-source Jun 2, 2026
7664eda
Configure environment-specific secrets management (#289)
ladinoraa Jun 2, 2026
643ff2d
Configure environment-specific secrets management (#289)
ladinoraa Jun 2, 2026
a7123fc
Configure environment-specific secrets management (#289)
ladinoraa Jun 2, 2026
66ba015
updates on proofwork
confima-source Jun 2, 2026
fb2e059
chore(deps): bump the patch-updates group with 6 updates (#449)
dependabot[bot] Jun 3, 2026
8af8479
chore(deps): bump the minor-updates group with 2 updates
dependabot[bot] Jun 3, 2026
1785971
Merge branch 'main' into dependabot/npm_and_yarn/minor-updates-ce4d04…
AnnabelJoe Jun 3, 2026
8ebc708
Merge pull request #450 from AnnabelJoe/dependabot/npm_and_yarn/minor…
AnnabelJoe Jun 3, 2026
91fc2b9
Merge pull request #448 from confima-source/feature/proofwork
AnnabelJoe Jun 3, 2026
8a2f59f
Merge pull request #447 from ladinoraa/issue-289-secrets-management
AnnabelJoe Jun 3, 2026
1b7d948
Merge pull request #446 from confima-source/feature/proof
AnnabelJoe Jun 3, 2026
6c51623
Merge branch 'main' into feature/security
AnnabelJoe Jun 3, 2026
48c6da7
Merge pull request #445 from woodlonestar-lang/feature/security
AnnabelJoe Jun 3, 2026
40e300d
Merge branch 'main' into feat/admin-ui-fractional-kwh
AnnabelJoe Jun 3, 2026
22924a2
Merge pull request #444 from doradenise-jpg/feat/admin-ui-fractional-kwh
AnnabelJoe Jun 3, 2026
ecccc4e
Merge branch 'main' into feat/fix
AnnabelJoe Jun 3, 2026
257fc75
Merge pull request #443 from devmasalati/feat/fix
AnnabelJoe Jun 3, 2026
5a92434
Merge branch 'main' into feat/fractional-kwh-tokens-354
AnnabelJoe Jun 3, 2026
e4544b7
Merge pull request #442 from Dev-Odun-oss/feat/fractional-kwh-tokens-354
AnnabelJoe Jun 3, 2026
a09f487
Merge branch 'main' into fix/e2e-token-expiry-https
AnnabelJoe Jun 3, 2026
f7d72b0
Merge pull request #441 from devoclan/fix/e2e-token-expiry-https
AnnabelJoe Jun 3, 2026
3fa702e
Merge branch 'main' into feat/issue-353-webhook-notifications
AnnabelJoe Jun 3, 2026
ceabb58
Merge pull request #440 from Sammy-Samy/feat/issue-353-webhook-notifi…
AnnabelJoe Jun 3, 2026
1845970
Merge pull request #439 from Sammy-Samy/feat/issue-347-bulk-retirement
AnnabelJoe Jun 3, 2026
315cb59
Merge pull request #438 from Sammy-Samy/feat/issue-342-pentest
AnnabelJoe Jun 3, 2026
c74344f
Merge pull request #437 from Sammy-Samy/feat/issue-352-public-verify-api
AnnabelJoe Jun 3, 2026
1cb7897
Merge branch 'main' into feature/issues-transfer-wallet-tracer-irec
AnnabelJoe Jun 3, 2026
049b764
Merge pull request #436 from jhayniffy/feature/issues-transfer-wallet…
AnnabelJoe Jun 3, 2026
1b86703
Merge branch 'main' into fix/341-audit-logging
AnnabelJoe Jun 3, 2026
4c6cc64
Merge pull request #435 from JosephOnuh/fix/341-audit-logging
AnnabelJoe Jun 3, 2026
b89dd7e
Merge pull request #434 from JosephOnuh/fix/344-license-compliance
AnnabelJoe Jun 3, 2026
7367043
Merge branch 'main' into fix/333-csp-headers
AnnabelJoe Jun 3, 2026
abd9139
Merge pull request #433 from JosephOnuh/fix/333-csp-headers
AnnabelJoe Jun 3, 2026
2019cd8
Merge branch 'main' into fix/340-security-headers
AnnabelJoe Jun 3, 2026
e061c41
Merge pull request #432 from JosephOnuh/fix/340-security-headers
AnnabelJoe Jun 3, 2026
578c482
Merge pull request #431 from josunday002/jobsunday
AnnabelJoe Jun 3, 2026
ac14fb9
Merge pull request #430 from sundayjob996/sundayjob
AnnabelJoe Jun 3, 2026
d279de3
Merge branch 'main' into feat/270-certificate-retirement
AnnabelJoe Jun 3, 2026
455bc44
Merge pull request #429 from devAgatha/feat/270-certificate-retirement
AnnabelJoe Jun 3, 2026
b20cb8e
Merge pull request #420 from Magada06/feature/274-rls-policies
AnnabelJoe Jun 3, 2026
c4c4466
Merge branch 'main' into issue-331-mutation-testing
AnnabelJoe Jun 3, 2026
cecac18
Merge pull request #425 from Philzwrist07/issue-331-mutation-testing
AnnabelJoe Jun 3, 2026
ca0a76d
Merge branch 'main' into docs/317-user-guide
AnnabelJoe Jun 3, 2026
4f6c85c
Merge pull request #419 from Magada06/docs/317-user-guide
AnnabelJoe Jun 3, 2026
acdb9b2
Merge pull request #422 from Philzwrist07/feat/287-contracts-ci
AnnabelJoe Jun 3, 2026
20f951f
Merge branch 'main' into issue-255-loading-skeletons
AnnabelJoe Jun 3, 2026
d9a528d
Merge pull request #421 from Magada06/issue-255-loading-skeletons
AnnabelJoe Jun 3, 2026
2b0a164
Merge pull request #389 from devnWisdom/docs/operational-runbooks-315
AnnabelJoe Jun 3, 2026
7a94632
Merge pull request #416 from pauljacobb/feat/260-realtime-chart-webso…
AnnabelJoe Jun 3, 2026
6be6abf
Merge branch 'main' into docs/319-rust-doc-comments
AnnabelJoe Jun 3, 2026
6aa00f9
Merge pull request #417 from pauljacobb/docs/319-rust-doc-comments
AnnabelJoe Jun 3, 2026
6e6a049
Merge pull request #423 from Philzwrist07/feat/142-mainnet-checklist
AnnabelJoe Jun 3, 2026
df0249d
Merge pull request #418 from pauljacobb/test/325-api-coverage-80
AnnabelJoe Jun 3, 2026
4e818f9
Merge pull request #415 from pauljacobb/feat/284-contract-upgrade-tim…
AnnabelJoe Jun 3, 2026
be84a17
Merge branch 'main' into feat/339-meter-revocation
AnnabelJoe Jun 3, 2026
42c92ab
Merge pull request #413 from ZainabJanee/feat/339-meter-revocation
AnnabelJoe Jun 3, 2026
c9667d2
Merge pull request #412 from ZainabJanee/ops/294-redis-persistence
AnnabelJoe Jun 3, 2026
cc3a363
Merge pull request #411 from ZainabJanee/docs/314-security-policy
AnnabelJoe Jun 3, 2026
06fd9c6
Merge pull request #386 from devnWisdom/docs/hardware-meter-integrati…
AnnabelJoe Jun 4, 2026
c8b8754
Merge pull request #387 from devnWisdom/devops/dependabot-setup-306
AnnabelJoe Jun 4, 2026
1edab51
Merge branch 'main' into devops/docker-resource-limits-304
AnnabelJoe Jun 4, 2026
0a176a6
Merge pull request #388 from devnWisdom/devops/docker-resource-limits…
AnnabelJoe Jun 4, 2026
fcfce35
Merge branch 'main' into feat/turbo-remote-cache-297
AnnabelJoe Jun 4, 2026
1803a1c
Merge pull request #390 from devUnixx/feat/turbo-remote-cache-297
AnnabelJoe Jun 4, 2026
172ca0b
Merge branch 'main' into feat/contract-event-tests-330
AnnabelJoe Jun 4, 2026
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
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ Closes #
- [ ] Tests pass
- [ ] No new lint warnings
- [ ] Docs updated if needed
- [ ] CHANGELOG.md updated
- [ ] PR targets `develop`
- [ ] Supabase queries audited for SQL injection (no raw SQL, parameterized methods used)
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ updates:
# Flag major version bumps for manual review
- dependency-name: "*"
update-types: [version-update:semver-major]

# GitHub Actions — monthly to reduce noise
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
open-pull-requests-limit: 5
labels:
- dependencies
- github-actions
ignore:
# Flag major version bumps for manual review
- dependency-name: "*"
update-types: [version-update:semver-major]
31 changes: 30 additions & 1 deletion .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
permissions:
contents: read
pull-requests: write
issues: write

jobs:
npm-audit:
Expand Down Expand Up @@ -42,6 +43,20 @@ jobs:
repo: context.repo.repo,
body: `### ${status} pnpm audit\n\`\`\`\n${output.slice(0, 6000)}\n\`\`\``
});
- name: Create Issue on failure (Scheduled)
if: github.event_name == 'schedule' && steps.npm_audit.outcome == 'failure'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const output = fs.readFileSync('/tmp/npm-audit.txt', 'utf8');
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '🚨 Weekly pnpm audit failed: High-severity vulnerabilities detected',
body: `The weekly pnpm audit found high-severity vulnerabilities in JS dependencies.\n\n### Audit Output:\n\`\`\`\n${output.slice(0, 6000)}\n\`\`\``,
labels: ['security', 'devops']
});
- name: Fail if audit found high/critical issues
if: steps.npm_audit.outcome == 'failure'
run: exit 1
Expand All @@ -54,7 +69,7 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.85.0"
toolchain: "1.88.0"
- uses: Swatinem/rust-cache@v2
with:
workspaces: apps/contracts
Expand All @@ -79,6 +94,20 @@ jobs:
repo: context.repo.repo,
body: `### ${status} cargo audit\n\`\`\`\n${output.slice(0, 6000)}\n\`\`\``
});
- name: Create Issue on failure (Scheduled)
if: github.event_name == 'schedule' && steps.cargo_audit.outcome == 'failure'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const output = fs.readFileSync('/tmp/cargo-audit.txt', 'utf8');
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '🚨 Weekly cargo audit failed: Vulnerabilities detected',
body: `The weekly cargo audit found vulnerabilities in Rust dependencies.\n\n### Audit Output:\n\`\`\`\n${output.slice(0, 6000)}\n\`\`\``,
labels: ['security', 'devops']
});
- name: Fail if audit found vulnerabilities
if: steps.cargo_audit.outcome == 'failure'
run: exit 1
82 changes: 78 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,26 @@ jobs:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- run: pnpm test
working-directory: apps/web
- name: Run tests with coverage
run: pnpm vitest run --coverage
working-directory: apps/web
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: apps/web/coverage/lcov.info
flags: web
fail_ci_if_error: false
- run: pnpm build
working-directory: apps/web
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL || 'https://placeholder.supabase.co' }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'placeholder' }}
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
NEXT_PUBLIC_STELLAR_NETWORK: testnet
NEXT_PUBLIC_ENERGY_TOKEN_ID: placeholder
NEXT_PUBLIC_AUDIT_REGISTRY_ID: placeholder
NEXT_PUBLIC_COMMUNITY_GOVERNANCE_ID: placeholder
SUPABASE_SERVICE_ROLE_KEY: placeholder
MINTER_SECRET_KEY: SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
MINTER_SECRET_KEY: ${{ secrets.MINTER_SECRET_KEY }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

Expand Down Expand Up @@ -104,6 +113,21 @@ jobs:
- name: Validate openapi.yaml
run: npx --yes @redocly/cli@1 lint openapi.yaml --format=github-actions

license-compliance:
name: License compliance check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: npx license-checker --onlyAllow "$(node -e "const c=require('./.license-checker.json');console.log(c.allowedLicenses.join(';'))")" --excludePrivatePackages

contracts:
name: Contracts (fmt + clippy + test)
runs-on: ubuntu-latest
Expand All @@ -128,14 +152,23 @@ jobs:
- name: fmt
run: cargo fmt --all -- --check
working-directory: apps/contracts
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

- name: clippy
run: cargo clippy --all-targets --all-features -- -D warnings
working-directory: apps/contracts
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

- name: test
run: cargo test --all
working-directory: apps/contracts
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}

proptest:
name: Property-based tests (proptest)
Expand Down Expand Up @@ -177,3 +210,44 @@ jobs:
- name: fuzz_vote (30 s)
run: cargo fuzz run fuzz_vote -- -max_total_time=30 corpus/fuzz_vote
working-directory: apps/contracts/fuzz

image-scan:
name: Docker image vulnerability scan (Trivy)
runs-on: ubuntu-latest
needs: web
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4

- name: Build Docker image
run: |
docker build \
--file apps/web/Dockerfile \
--tag solarproof/web:${{ github.sha }} \
.

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: solarproof/web:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: CRITICAL
exit-code: '1'
ignore-unfixed: true

- name: Upload Trivy SARIF results as artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: trivy-scan-results
path: trivy-results.sarif
retention-days: 30

- name: Upload SARIF to GitHub Security tab
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
48 changes: 48 additions & 0 deletions .github/workflows/contracts-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Contracts CI

on:
pull_request:
branches: [main, develop]
paths:
- "apps/contracts/**"
- ".github/workflows/contracts-ci.yml"
push:
branches: [main, develop]
paths:
- "apps/contracts/**"
- ".github/workflows/contracts-ci.yml"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Rust contracts (fmt + clippy + test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.85.0"
targets: wasm32-unknown-unknown
components: rustfmt, clippy

- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
workspaces: apps/contracts

- name: Check formatting
run: cargo fmt --all -- --check
working-directory: apps/contracts

- name: Clippy
run: cargo clippy --all-targets --all-features -- -D warnings
working-directory: apps/contracts

- name: Run tests
run: cargo test --all
working-directory: apps/contracts
49 changes: 49 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Deploy Production

on:
push:
branches: [main]

jobs:
ci:
name: CI gate
uses: ./.github/workflows/ci.yml
secrets: inherit

deploy:
name: Deploy to Vercel (production)
runs-on: ubuntu-latest
needs: ci
permissions:
deployments: write
environment:
name: production
url: ${{ steps.promote.outputs.url }}
steps:
- uses: actions/checkout@v4

- name: Install Vercel CLI
run: npm install -g vercel@latest

- name: Build & deploy preview (green)
id: deploy
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: |
url=$(vercel deploy --token "$VERCEL_TOKEN" --yes 2>&1 | tail -1)
echo "url=$url" >> "$GITHUB_OUTPUT"

- name: Promote to production
id: promote
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
run: |
vercel promote "${{ steps.deploy.outputs.url }}" \
--token "$VERCEL_TOKEN" --scope "$VERCEL_ORG_ID"
echo "url=${{ steps.deploy.outputs.url }}" >> "$GITHUB_OUTPUT"

- name: Write deployment URL to job summary
run: echo "### 🚀 Production deployed to ${{ steps.promote.outputs.url }}" >> "$GITHUB_STEP_SUMMARY"
85 changes: 85 additions & 0 deletions .github/workflows/mutation-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Mutation Testing

on:
schedule:
# Every Sunday at 02:00 UTC
- cron: '0 2 * * 0'
workflow_dispatch:
inputs:
target:
description: 'Which target to run (all | rust | typescript)'
required: false
default: 'all'

concurrency:
group: mutation-testing
cancel-in-progress: true

jobs:
rust-mutations:
name: Rust (cargo-mutants)
if: ${{ github.event_name == 'schedule' || github.event.inputs.target == 'all' || github.event.inputs.target == 'rust' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: '1.85.0'
targets: wasm32-unknown-unknown

- uses: Swatinem/rust-cache@v2
with:
workspaces: apps/contracts

- name: Install cargo-mutants
run: cargo install cargo-mutants --locked --version 24.11.0

- name: Run cargo-mutants
working-directory: apps/contracts
run: |
cargo mutants \
--package audit_registry \
--package energy_token \
--output mutants-out \
--timeout 120 \
--jobs 2

- name: Upload mutation report
if: always()
uses: actions/upload-artifact@v4
with:
name: cargo-mutants-report
path: apps/contracts/mutants-out/
retention-days: 30

typescript-mutations:
name: TypeScript (Stryker)
if: ${{ github.event_name == 'schedule' || github.event.inputs.target == 'all' || github.event.inputs.target == 'typescript' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
version: 10

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Run Stryker
working-directory: packages/stellar
run: pnpm test:mutation

- name: Upload Stryker report
if: always()
uses: actions/upload-artifact@v4
with:
name: stryker-report
path: packages/stellar/reports/mutation/
retention-days: 30
Loading
Loading