mirror of
https://github.com/waaraawa/ByteGrid.git
synced 2026-07-22 06:41:47 +00:00
chore: add Obsidian scorecard preflight checks
This commit is contained in:
parent
e68a0f3733
commit
98e42aea3d
7 changed files with 6011 additions and 5 deletions
60
.github/workflows/release.yml
vendored
Normal file
60
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Prepare release assets
|
||||
run: |
|
||||
mkdir -p release
|
||||
cp packages/obsidian-plugin/main.js release/main.js
|
||||
cp packages/obsidian-plugin/styles.css release/styles.css
|
||||
cp manifest.json release/manifest.json
|
||||
|
||||
- name: Attest release assets
|
||||
uses: actions/attest-build-provenance@v2
|
||||
with:
|
||||
subject-path: release/*
|
||||
|
||||
- name: Ensure GitHub release exists
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh release view "${GITHUB_REF_NAME}" ||
|
||||
gh release create "${GITHUB_REF_NAME}" \
|
||||
--title "${GITHUB_REF_NAME}" \
|
||||
--notes "Release ${GITHUB_REF_NAME}"
|
||||
|
||||
- name: Upload release assets
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: gh release upload "${GITHUB_REF_NAME}" release/* --clobber
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,6 +1,5 @@
|
|||
# Dependencies
|
||||
node_modules/
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
# Build outputs
|
||||
|
|
|
|||
5852
package-lock.json
generated
Normal file
5852
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,7 @@
|
|||
"build": "npm run build --workspaces",
|
||||
"test": "npm run test --workspaces --if-present",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"check:scorecard": "node scripts/check-scorecard.mjs",
|
||||
"format": "prettier --write \"**/*.{ts,json,md}\"",
|
||||
"format:check": "prettier --check \"**/*.{ts,json,md}\"",
|
||||
"clean": "rm -rf packages/*/dist packages/*/node_modules node_modules"
|
||||
|
|
@ -27,8 +28,9 @@
|
|||
"devDependencies": {
|
||||
"@types/jest": "^29.5.11",
|
||||
"@types/node": "^20.10.6",
|
||||
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
||||
"@typescript-eslint/parser": "^6.17.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.61.1",
|
||||
"@typescript-eslint/parser": "^8.61.1",
|
||||
"esbuild": "^0.28.1",
|
||||
"eslint": "^8.56.0",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.1",
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
"devDependencies": {
|
||||
"@types/node": "^20.10.6",
|
||||
"builtin-modules": "^3.3.0",
|
||||
"esbuild": "^0.19.11",
|
||||
"esbuild": "^0.28.1",
|
||||
"obsidian": "^1.4.16",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
}
|
||||
|
||||
.theme-dark .bytegrid-source {
|
||||
background-color: #374151 !important;
|
||||
background-color: #374151;
|
||||
color: #e5e7eb;
|
||||
}
|
||||
|
||||
|
|
|
|||
93
scripts/check-scorecard.mjs
Normal file
93
scripts/check-scorecard.mjs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const ROOT = process.cwd();
|
||||
const IGNORED_DIRS = new Set(['coverage', 'dist', 'node_modules']);
|
||||
|
||||
const checks = [];
|
||||
|
||||
function addCheck(name, run) {
|
||||
checks.push({ name, run });
|
||||
}
|
||||
|
||||
function listFiles(dir, predicate = () => true) {
|
||||
if (!fs.existsSync(dir)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
return entries.flatMap((entry) => {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
if (IGNORED_DIRS.has(entry.name)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return listFiles(fullPath, predicate);
|
||||
}
|
||||
|
||||
return predicate(fullPath) ? [fullPath] : [];
|
||||
});
|
||||
}
|
||||
|
||||
addCheck('No CSS !important usage', () => {
|
||||
const cssFiles = listFiles(path.join(ROOT, 'packages'), (file) => file.endsWith('.css'));
|
||||
const violations = cssFiles.flatMap((file) => {
|
||||
const content = fs.readFileSync(file, 'utf8');
|
||||
return content
|
||||
.split('\n')
|
||||
.map((line, index) => ({ file, line, lineNumber: index + 1 }))
|
||||
.filter(({ line }) => line.includes('!important'));
|
||||
});
|
||||
|
||||
if (violations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const details = violations
|
||||
.map(({ file, lineNumber }) => `${path.relative(ROOT, file)}:${lineNumber}`)
|
||||
.join('\n');
|
||||
throw new Error(`Avoid !important in plugin CSS:\n${details}`);
|
||||
});
|
||||
|
||||
addCheck('Committed npm lockfile exists', () => {
|
||||
const lockfile = path.join(ROOT, 'package-lock.json');
|
||||
|
||||
if (!fs.existsSync(lockfile)) {
|
||||
throw new Error('package-lock.json is required for reproducible dependency resolution');
|
||||
}
|
||||
});
|
||||
|
||||
addCheck('Release workflow includes artifact attestation', () => {
|
||||
const workflowDir = path.join(ROOT, '.github', 'workflows');
|
||||
const workflowFiles = listFiles(workflowDir, (file) => /\.(ya?ml)$/.test(file));
|
||||
|
||||
const hasAttestation = workflowFiles.some((file) => {
|
||||
const content = fs.readFileSync(file, 'utf8');
|
||||
return content.includes('actions/attest-build-provenance');
|
||||
});
|
||||
|
||||
if (!hasAttestation) {
|
||||
throw new Error(
|
||||
'release workflow should attest release assets with actions/attest-build-provenance'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const failures = [];
|
||||
|
||||
for (const check of checks) {
|
||||
try {
|
||||
check.run();
|
||||
console.log(`PASS ${check.name}`);
|
||||
} catch (error) {
|
||||
failures.push({ name: check.name, error });
|
||||
console.error(`FAIL ${check.name}`);
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
Loading…
Reference in a new issue