enhance(dev): add linters and workflow for publish

to have basic code quality checks. Test worker asset builds
successfully Also fix minor things caught by clj-kondo and carve.
This commit is contained in:
Gabriel Horner
2026-01-21 15:34:22 -05:00
parent 3e0d57bc32
commit cd8f312b9f
9 changed files with 178 additions and 17 deletions

103
.github/workflows/deps-publish.yml vendored Normal file
View File

@@ -0,0 +1,103 @@
name: logseq/publish CI
on:
# Path filters ensure jobs only kick off if a change is made to publish or
# its local dependencies
push:
branches: [master]
paths:
- 'deps/publish/**'
- '.github/workflows/deps-publish.yml'
- '!deps/publish/**.md'
# Deps that logseq/publish depends on should trigger this workflow
- 'deps/graph-parser/**'
- 'deps/db/**'
- 'deps/common/**'
pull_request:
branches: [master]
paths:
- 'deps/publish/**'
- '.github/workflows/deps-publish.yml'
- '!deps/publish/**.md'
# Deps that logseq/publish depends on should trigger this workflow
- 'deps/graph-parser/**'
- 'deps/db/**'
- 'deps/common/**'
defaults:
run:
working-directory: deps/publish
env:
CLOJURE_VERSION: '1.11.1.1413'
# This is the same as 1.8.
JAVA_VERSION: '11'
# This is the latest node version we can run.
NODE_VERSION: '22'
BABASHKA_VERSION: '1.0.168'
jobs:
test-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
cache-dependency-path: deps/publish/yarn.lock
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: ${{ env.JAVA_VERSION }}
# Clojure needed for bb step
- name: Set up Clojure
uses: DeLaGuardo/setup-clojure@10.1
with:
cli: ${{ env.CLOJURE_VERSION }}
bb: ${{ env.BABASHKA_VERSION }}
- name: Fetch yarn deps
run: yarn install --frozen-lockfile
- name: Build release asset
run: yarn release
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: ${{ env.JAVA_VERSION }}
- name: Set up Clojure
uses: DeLaGuardo/setup-clojure@10.1
with:
cli: ${{ env.CLOJURE_VERSION }}
bb: ${{ env.BABASHKA_VERSION }}
- name: Run clj-kondo lint
run: clojure -M:clj-kondo --lint src
- name: Carve lint for unused vars
run: bb lint:carve
- name: Lint for vars that are too large
run: bb lint:large-vars
# TODO: Add docstrings
# - name: Lint for namespaces that aren't documented
# run: bb lint:ns-docstrings

3
deps/publish/.carve/config.edn vendored Normal file
View File

@@ -0,0 +1,3 @@
{:paths ["src"]
:api-namespaces [logseq.publish.worker]
:report {:format :ignore}}

18
deps/publish/.clj-kondo/config.edn vendored Normal file
View File

@@ -0,0 +1,18 @@
{:linters
{:aliased-namespace-symbol {:level :warning}
:namespace-name-mismatch {:level :warning}
:used-underscored-binding {:level :warning}
:shadowed-var {:level :warning
:exclude [meta name key keys uuid type]}
:consistent-alias
{:aliases {clojure.pprint pprint
clojure.string string
datascript.core d
datascript.transit dt
logseq.publish.common publish-common
logseq.publish.model publish-model}}}
:lint-as {logseq.publish.async/js-await clojure.core/let
shadow.cljs.modern/defclass clj-kondo.lint-as/def-catch-all}
:skip-comments true
:output {:progress true}}

1
deps/publish/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.clj-kondo/.cache

View File

@@ -20,6 +20,10 @@ This module is intended to be consumed by the Logseq app and the publishing work
## Dev
Keep this module aligned with the main repo's linting and testing conventions.
Most of the same linters are used, with configurations that are specific to this
library. See [this library's CI file](/.github/workflows/deps-publish.yml) for
linting examples.
### Local Testing

31
deps/publish/bb.edn vendored Normal file
View File

@@ -0,0 +1,31 @@
{:min-bb-version "1.0.168"
:deps
{logseq/bb-tasks
#_{:local/root "../../../bb-tasks"}
{:git/url "https://github.com/logseq/bb-tasks"
:git/sha "70d3edeb287f5cec7192e642549a401f7d6d4263"}}
:pods
{clj-kondo/clj-kondo {:version "2024.09.27"}}
:tasks
{test:load-all-namespaces-with-nbb
logseq.bb-tasks.nbb.test/load-all-namespaces
lint:large-vars
logseq.bb-tasks.lint.large-vars/-main
lint:carve
logseq.bb-tasks.lint.carve/-main
lint:ns-docstrings
logseq.bb-tasks.lint.ns-docstrings/-main
lint:minimize-public-vars
logseq.bb-tasks.lint.minimize-public-vars/-main}
:tasks/config
{:large-vars
{:metadata-exceptions #{:large-vars/cleanup-todo}
;; AI generated code has its tradeoffs
:max-lines-count 150}}}

View File

@@ -104,7 +104,7 @@
"content_hash" (get data "content_hash")
"content_length" (get data "content_length"))))
(defn do-fetch [^js self request]
(defn ^:large-vars/cleanup-todo do-fetch [^js self request]
(let [sql (.-sql self)]
(init-schema! sql)
(cond

View File

@@ -712,8 +712,8 @@
items)))
(defn- block-ast->nodes
[ctx block-ast]
(let [[type data] block-ast]
[ctx block-ast']
(let [[type data] block-ast']
(case type
"Paragraph"
(let [children (inline-coll->nodes ctx data)]
@@ -869,7 +869,7 @@
(defn- asset-node [block ctx]
(let [asset-type (:logseq.property.asset/type block)
asset-url (asset-url block ctx)
asset-url' (asset-url block ctx)
external-url (:logseq.property.asset/external-url block)
title (or (:block/title block) (str asset-type))
ext (string/lower-case (or asset-type ""))
@@ -888,27 +888,27 @@
width
"w"))))
(string/join ", ")))]
(when asset-url
(when asset-url'
(cond
(contains? #{"png" "jpg" "jpeg" "gif" "webp" "svg" "bmp" "avif"} ext)
[:img.asset-image (cond-> {:src asset-url :alt title}
[:img.asset-image (cond-> {:src asset-url' :alt title}
srcset (assoc :srcset srcset :sizes publish-image-sizes-attr))]
(contains? #{"mp4" "webm" "mov"} ext)
[:video.asset-video {:src asset-url :controls true}]
[:video.asset-video {:src asset-url' :controls true}]
(contains? #{"mp3" "wav" "ogg"} ext)
[:audio.asset-audio {:src asset-url :controls true}]
[:audio.asset-audio {:src asset-url' :controls true}]
:else
[:a.asset-link {:href asset-url :target "_blank"} title]))))
[:a.asset-link {:href asset-url' :target "_blank"} title]))))
(defn block-display-node [block ctx depth]
(let [display-type (:logseq.property.node/display-type block)
asset-node (when (:logseq.property.asset/type block)
asset-node' (when (:logseq.property.asset/type block)
(asset-node block ctx))]
(case display-type
:asset asset-node
:asset asset-node'
:code
(let [lang (:logseq.property.code/lang block)
attrs (cond-> {:class "code-block"}
@@ -921,7 +921,7 @@
:quote
[:blockquote.quote-block (block-content-nodes block ctx depth)]
(or asset-node
(or asset-node'
(block-content-nodes block ctx depth)))))
(defn block-content-from-ref [ref ctx]
@@ -1085,7 +1085,7 @@
distinct
sort)))
(defn render-page-html
(defn ^:large-vars/cleanup-todo render-page-html
[transit page-uuid-str refs-data tagged-nodes]
(let [payload (publish-common/read-transit-safe transit)
meta (publish-common/get-publish-meta payload)

View File

@@ -12,7 +12,8 @@
(def publish-css (resource/inline "logseq/publish/publish.css"))
(def publish-js (resource/inline "logseq/publish/publish.js"))
(def tabler-ext-js (resource/inline "js/tabler.ext.js"))
(def tabler-extension-css (resource/inline "css/tabler-extension.css"))
;; Should this be used?
;; (def tabler-extension-css (resource/inline "css/tabler-extension.css"))
(defn- request-password
[request]
@@ -461,8 +462,8 @@
(js-await [meta (.json meta-resp)
owner-sub (aget meta "owner_sub")
subject (aget claims "sub")]
(if (and (or (string/blank? owner-sub)
(not= owner-sub subject)))
(if (or (string/blank? owner-sub)
(not= owner-sub subject))
(publish-common/forbidden)
(js-await [page-resp (.fetch page-stub (str "https://publish/pages/" graph-uuid "/" page-uuid)
#js {:method "DELETE"})
@@ -599,7 +600,7 @@
(publish-render/render-page-html transit page-uuid refs-json tagged-nodes)
#js {:headers headers})))))))))))))
(defn handle-fetch [request env]
(defn ^:large-vars/cleanup-todo handle-fetch [request env]
(let [url (js/URL. (.-url request))
path (.-pathname url)
method (.-method request)]