{"id":23436901,"url":"https://github.com/logseq/graph-validator","last_synced_at":"2025-04-13T04:42:34.338Z","repository":{"id":40781562,"uuid":"507076130","full_name":"logseq/graph-validator","owner":"logseq","description":"Validate your logseq graphs","archived":false,"fork":false,"pushed_at":"2023-08-04T19:34:37.000Z","size":904,"stargazers_count":48,"open_issues_count":2,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-13T04:42:18.918Z","etag":null,"topics":["github-actions","logseq","nbb"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/logseq.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-06-24T16:28:03.000Z","updated_at":"2024-11-08T13:27:08.000Z","dependencies_parsed_at":"2023-02-18T00:30:40.900Z","dependency_job_id":null,"html_url":"https://github.com/logseq/graph-validator","commit_stats":{"total_commits":62,"total_committers":1,"mean_commits":62.0,"dds":0.0,"last_synced_commit":"c74ffe9f0fa44632580b1455dcca7e816b8ed38f"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fgraph-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fgraph-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fgraph-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logseq%2Fgraph-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/logseq","download_url":"https://codeload.github.com/logseq/graph-validator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665782,"owners_count":21142123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-actions","logseq","nbb"],"created_at":"2024-12-23T13:34:50.722Z","updated_at":"2025-04-13T04:42:34.308Z","avatar_url":"https://github.com/logseq.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Description\n\nThis is a [github action](https://github.com/features/actions) to run\n[validations](#validations) on a Logseq graph. This action can also be run as a\n[CLI](#cli). Validations check to ensure queries, block refs and properties are\nvalid. This action can catch errors that show up in the UI e.g. `Invalid query`.\n\n## Usage\n\nTo setup this action, add the file `.github/workflows/test.yml` to your graph's\ngithub repository with the following content:\n\n``` yaml\non: [push]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    name: Run graph tests\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Run graph-validator tests\n        uses: logseq/graph-validator@main\n```\n\nThat's it! This job will then run on future git pushes and fail if any invalid parts\nof your graph are detected.\n\nNOTE: The above example defaults to picking up new changes. If you'd prefer to stay on a stable version use the format `logseq/graph-validator@VERSION` e.g. `logseq/graph-validator@v0.1.0`. See CHANGELOG.md for released versions.\n\n### Action Inputs\n\nThis action can take inputs e.g.:\n\n```yaml\n- name: Run graph-validator tests\n  uses: logseq/graph-validator@main\n  with:\n    directory: logseq-graph-directory\n    exclude: some-validation-test\n```\n\nThis action has the following inputs:\n\n#### `directory`\n\n**Required:** The directory of the graph to test. Defaults to `.`.\n\n#### `exclude`\n\nOptional: A whitespace separated list of validations to exclude from running.\nValidation names are listed in [default validations](#default-validations) e.g.\n`tags-and-page-refs-have-pages`. Defaults to empty.\n\n### CLI\n\nTo use this as a CLI locally, first install\n[babashka](https://github.com/babashka/babashka#installation) and\n[clojure](https://clojure.org/guides/install_clojure). Then:\n\n```sh\n$ git clone https://github.com/logseq/graph-validator\n$ cd graph-validator \u0026\u0026 yarn install\n$ yarn global add $PWD\n```\n\nThen use it from any logseq graph directory!\n```sh\n$ logseq-graph-validator\nParsing graph .\n...\nRan 6 tests containing 9 assertions.\n0 failures, 0 errors.\n\n# Use the exclude option to exclude certain validations from being run\n$ logseq-graph-validator --exclude assets-exist-and-are-used tags-and-page-refs-have-pages\nExcluded test #'action/assets-exist-and-are-used\nExcluded test #'action/tags-and-page-refs-have-pages\nParsing graph .\n...\nRan 4 tests containing 5 assertions.\n0 failures, 0 errors.\n```\n\nNOTE: Running the CLI currently depends on a clean git state e.g. `git status` prints `nothing to\ncommit, working tree clean`.\n\n## Configuration\n\nTo configure the validator, create a `.graph-validator/config.edn` file in your\ngraph's directory. See [the config\nfile](https://github.com/logseq/graph-validator/blob/main/src/logseq/graph_validator/config.cljs)\nfor the full list of configuration keys.\n\n## Validations\n\nValidations runs on _all_ files for a given graph. A validation prints if it\nfails. A validation can have multiple errors. For engineers, a validation is\njust a ClojureScript `deftest`.\n\n### Default Validations\n\nThese are validations that are enabled by default. Any of them can be disabled\nwith the `exclude` option above. Available validations:\n\n- `block-refs-link-to-blocks-that-exist` - If a block ref e.g.\n  `((694dc3ff-e714-4db0-8b36-58f2ff0b48a4))` links to a nonexistent block,\n  Logseq displays it as invalid. This validation prints all such invalid block ids.\n- `embed-block-refs-link-to-blocks-that-exist` - Similar to\n  `block-refs-link-to-blocks-that-exist`, if an embedded block ref is invalid,\n  this validation prints its corresponding invalid block id.\n- `advanced-queries-have-valid-schema` - If an [advanced query](https://docs.logseq.com/#/page/advanced%20queries)\n  is not a valid map or missing required keys, this validation prints those\n  queries.\n- `invalid-properties-dont-exist` - A\n  [property](https://docs.logseq.com/#/page/properties/block/usage) can get in\n  an invalid state with invalid names. This validation prints those invalid\n  properties.\n- `assets-exist-and-are-used` - This validation catches two types of common\n  issues with invalid assets - asset links that point to assets that don't exist\n  and assets that are not referenced anywhere in the graphs.\n- `tags-and-page-refs-have-pages` - This validation prints all tags and page\n  refs that don't have a Logseq page. This is useful for those using Logseq more\n  like a personal wikipedia and want to ensure that each link has meaningful content.\n\n### Custom Validations\n\nCustom validations can be added to your graph by writing nbb-logseq compatible\n[cljs tests](https://clojurescript.org/tools/testing) under `.graph-validator/`.\ngraph-validator already handles parsing the graph, so all a test does is\nquery against the graph's datascript db, `logseq.graph-parser.state/db-conn`. See\n`logseq.graph-parser.state` for other available state to use in tests. For\nexample, add a `.graph-validator/foo.cljs` with the content:\n\n```cljs\n(ns foo\n  (:require [cljs.test :refer [deftest is]]\n            [logseq.graph-validator.state :as state]\n            [datascript.core :as d]))\n\n(deftest no-page-named-foo\n  (is (= 0\n         (-\u003e\u003e (d/q '[:find (pull ?b [*])\n                     :in $ ?name\n                     :where\n                     [?b :block/name ?bn]\n                     [(= ?name ?bn)]]\n                   @state/db-conn\n                   \"foo\")\n              count))))\n```\n\nThis test does a silly check that the page 'foo' doesn't exist in the graph. To\nenable this custom test in your action, create `.graph-validator/config.edn`\nwith `{:add-namespaces [foo]}`.\n\nFor a real world example of a custom validation, see [this example in docs](https://github.com/logseq/docs/blob/master/.graph-validator/schema.cljs).\n\n## Development\n\nThis github action use [nbb-logseq](https://github.com/logseq/nbb-logseq) and the [graph-parser\nlibrary](https://github.com/logseq/logseq/tree/master/deps/graph-parser) to analyze a Logseq graph\nusing its database and markdown AST data.\n\n## Write your own Logseq action\n\nThis github action serves as an example that can be easily customized. This\naction can validate almost anything in a Logseq graph as it has access to the\ngraph's database connection and to the full markdown AST of a graph. To write\nyour own action:\n\n1. Copy this whole repository.\n2. Write your own implementation in `action.cljs`.\n   1. `logseq.graph-parser.cli/parse-graph` is the fn you'll want to create a database connection and fetch markdown ast data.\n   2. This example uses `cljs.test` tests to run multiple validations on a graph. This is a personal preference and ultimately you only need your script to exit `0` on success and a non-zero code on failure.\n3. Update `action.yml` with your action's name, description and inputs.\n\nYour action can then be used as `user/repo@main`. To allow others to use specific versions of your action, [publish it](https://docs.github.com/en/actions/creating-actions/publishing-actions-in-github-marketplace).\n\n### Github action type\n\nThis action [is a composite action](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action) that installs dependencies at job runtime. It would have been preferable to use a [javascript action](https://docs.github.com/en/actions/creating-actions/creating-a-javascript-action) that already bundles dependencies with a tool like `ncc`. `ncc` is not able to handle dynamic imports i.e. requires of npm libraries in cljs code. https://github.com/borkdude/nbb-action-example demonstrates a workaround for this. Unfortunately the graph-parser library is a large, fast-moving library that would be difficult to maintain with such an approach. A docker action approach has not been investigated and could also be promising.\n\n### Run this action elsewhere\n\nYou may want to run this locally or in another environment e.g. gitlab. To run this locally:\n\n```sh\n# Setup once\n$ yarn install\n\n# Run this each time\n$ node graph_validator.mjs /path/to/graph\n```\n\nTo run this in another environment, clone this repo, install dependencies and\nrun tests. These steps are shown in the `action.yml` file. You can ignore the\ncaching steps which are specific to github.\n\n## LICENSE\nSee LICENSE.md\n\n## Additional Links\n* https://github.com/borkdude/nbb-action-example - Example nbb github action that inspired this one\n* https://github.com/logseq/docs - Logseq graph that uses this action\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogseq%2Fgraph-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flogseq%2Fgraph-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogseq%2Fgraph-validator/lists"}