Skip to content

Commit b88f4c7

Browse files
Automatically generate contracts documentation
We are creating a GH Actions workflow which automatically generates the contracts documentation in Markdown, based on the functions and the NatSpec-format comments in the Solidity files stored in the `contracts` folder in `threshold-network/solidity-contracts`. For certain workflow triggers, the generated documentation will be pushed to the `threshold-network/threshold` repository, under `./docs/app-development/staking-contract-and-dao/staking-contract-and-dao-api`. As the `.docs` folder is synched with Threshold docs GitBook space, the pushed docs will be displayed in HTML under `docs.threshold.network` domain. There are two main jobs in the workflow: * `contracts-docs-publish-preview` * `contracts-docs-publish` Both call a reusable workflow `reusable-solidity-docs.yml` which resides in the `keep-network/ci` repository under `.github/workflows`. The jobs differ in parameters with witch the reusable action is called. The common part of the jobs is the beginning stage, where the Solidity files are being prepared for Markdown generation. During that stage the jobs will remove the spaces chars between the NatSpec comments markers (`///`) and the text of the comment. This is done to ensure proper rendering of the lists in the output docs and is a default action made by `reusable-solidity-docs.yml`. Once files are ready, the jobs use Docgen tool to generate the Markdown docs. The tool needs to be installed in the project and configured in the `hardhat.config.ts`. The configuration that we use specifies that the docs should be generated to the `geerated-docs` subfolder, to one single `index.md` file. The `.sol` files in the `./solidity/contracts/test` folder will be ignored during generation (those are test/stub contracts which are not used on Mainnet). A custom template will be used during docs generations. The template was created based on the default https://github.com/OpenZeppelin/solidity-docgen/blob/master/src/themes/markdown/common.hbs template, but it removes the cursive from the `@dev` type comments (because the cursive didn't work well with formatting of the lists). Once the Docgen is run and the `index.md` file is generated, the jobs will add a Table of Contents to the file, to improve the navigation. The TOC will be added by the `markdown-toc` tool and will be generated using `--maxdepth 2` param, which results in listing all the contract names, but not the functions. Once the TOC is added, we'll start to see the difference in the behavior of the jobs. The `contracts-docs-publish-preview` job is triggered for: * `pull_request` events, if the PR modifies either files in `./contracts` or the workflow file itself, * `push` events, when the push is made to a branch which name starts with `releases/mainnet/v`, * `workflow_dispatch` events. The job publishes the generated artifacts as artifacts of the GH Actions workflow run. For PRs, link to the run with the artifacts will be posted as a PR comment. The `contracts-docs-publish` job is triggered for: * published releases, which names start with `refs/tags/v`. The job pushes the generated file to the `./docs/app-development/staking-contract-and-dao/staking-contract-and-dao-api` folder in the `threshold-network/threshold` repo, to the `main` branch. The `.docs` folder is synched with the GitBook Threshold documentation, so thanks to the job, the changes in the contracts should be reflected on the docs.threshold.network. In order for the job to work, we need to configure a user which will create the commit The user needs to have right to commit to the `threshold-network/threshold` repo. We also need to configure following secrets: - [ ] `THRESHOLD_DOCS_GITHUB_TOKEN` - [ ] `GPG_PRIVATE_KEY` - [ ] `GPG_PASSPHRASE` We're using a GPG key to be able to do verified commits.
1 parent 7ed8000 commit b88f4c7

File tree

6 files changed

+153
-1
lines changed

6 files changed

+153
-1
lines changed

.github/workflows/contracts-docs.yaml

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Solidity docs
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- releases/mainnet/v**
8+
release:
9+
types:
10+
- "published"
11+
workflow_dispatch:
12+
13+
jobs:
14+
docs-detect-changes:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
path-filter: ${{ steps.filter.outputs.path-filter }}
18+
steps:
19+
- uses: actions/checkout@v3
20+
if: github.event_name == 'pull_request'
21+
- uses: dorny/paths-filter@v2
22+
if: github.event_name == 'pull_request'
23+
id: filter
24+
with:
25+
filters: |
26+
path-filter:
27+
- './contracts/**'
28+
- './.github/workflows/contracts-docs.yml'
29+
30+
# This job will be triggered for PRs which modify contracts. It will generate
31+
# the archive with contracts documentation in Markdown and attatch it to the
32+
# workflow run results. Link to the archive will be posted in a PR comment.
33+
# The job will also be run after manual triggering and after pushes to the
34+
# `releases/mainnet/**` branches.
35+
contracts-docs-publish-preview:
36+
name: Publish preview of contracts documentation
37+
needs: docs-detect-changes
38+
if: |
39+
github.event_name == 'pull_request'
40+
|| github.event_name == 'push'
41+
|| github.event_name == 'workflow_dispatch'
42+
uses: keep-network/ci/.github/workflows/reusable-solidity-docs.yml@main
43+
with:
44+
publish: false
45+
commentPR: true
46+
exportAsGHArtifacts: true
47+
48+
# This job will be triggered for releases which name starts with
49+
# `refs/tags/v`. It will generate contracts documentation in
50+
# Markdown and sync it with a specific path of
51+
# `threshold-network/threshold` repository. If changes will be detected,
52+
# the destination repository will be updated. The commit pushing the
53+
# changes will be verified using GPG key.
54+
contracts-docs-publish:
55+
name: Publish contracts documentation
56+
needs: docs-detect-changes
57+
if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v')
58+
uses: keep-network/ci/.github/workflows/reusable-solidity-docs.yml@main
59+
with:
60+
publish: true
61+
verifyCommits: true
62+
destinationRepo: threshold-network/threshold
63+
destinationFolder: ./docs/app-development/staking-contract-and-dao/staking-contract-and-dao-api
64+
destinationBranch: main
65+
userEmail: [email protected]
66+
userName: Valkyrie
67+
secrets:
68+
githubToken: ${{ secrets.THRESHOLD_DOCS_GITHUB_TOKEN }}
69+
gpgPrivateKey: ${{ secrets.GPG_PRIVATE_KEY }}
70+
gpgPassphrase: ${{ secrets.GPG_PASSPHRASE }}

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ artifacts/
33
build/
44
cache/
55
deployments/
6+
docgen-templates/
67
export/

docgen-templates/common.hbs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{{h}} {{name}}
2+
3+
{{#if signature}}
4+
```solidity
5+
{{{signature}}}
6+
```
7+
{{/if}}
8+
9+
{{{natspec.notice}}}
10+
11+
{{#if natspec.dev}}
12+
{{{natspec.dev}}}
13+
{{/if}}
14+
15+
{{#if natspec.params}}
16+
{{h 2}} Parameters
17+
18+
| Name | Type | Description |
19+
| ---- | ---- | ----------- |
20+
{{#each params}}
21+
| {{name}} | {{type}} | {{{joinLines natspec}}} |
22+
{{/each}}
23+
{{/if}}
24+
25+
{{#if natspec.returns}}
26+
{{h 2}} Return Values
27+
28+
| Name | Type | Description |
29+
| ---- | ---- | ----------- |
30+
{{#each returns}}
31+
| {{#if name}}{{name}}{{else}}[{{@index}}]{{/if}} | {{type}} | {{{joinLines natspec}}} |
32+
{{/each}}
33+
{{/if}}

hardhat.config.ts

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import "@tenderly/hardhat-tenderly"
88
import "hardhat-contract-sizer"
99
import "hardhat-deploy"
1010
import "hardhat-gas-reporter"
11+
import "solidity-docgen"
1112

1213
const config: HardhatUserConfig = {
1314
solidity: {
@@ -135,6 +136,12 @@ const config: HardhatUserConfig = {
135136
mocha: {
136137
timeout: 60000,
137138
},
139+
docgen: {
140+
outputDir: "generated-docs",
141+
templates: "docgen-templates",
142+
pages: "single", // `single`, `items` or `files`
143+
exclude: ["./test"],
144+
},
138145
}
139146

140147
export default config

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"prettier-plugin-solidity": "^1.0.0-beta.14 ",
5555
"solhint": "^3.3.6",
5656
"solhint-config-keep": "github:keep-network/solhint-config-keep",
57+
"solidity-docgen": "^0.6.0-beta.35",
5758
"ts-node": "^10.4.0",
5859
"typescript": "^4.4.4"
5960
},

yarn.lock

+41-1
Original file line numberDiff line numberDiff line change
@@ -5688,6 +5688,18 @@ [email protected]:
56885688
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
56895689
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
56905690

5691+
handlebars@^4.7.7:
5692+
version "4.7.7"
5693+
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
5694+
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
5695+
dependencies:
5696+
minimist "^1.2.5"
5697+
neo-async "^2.6.0"
5698+
source-map "^0.6.1"
5699+
wordwrap "^1.0.0"
5700+
optionalDependencies:
5701+
uglify-js "^3.1.4"
5702+
56915703
har-schema@^2.0.0:
56925704
version "2.0.0"
56935705
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@@ -7609,6 +7621,11 @@ [email protected]:
76097621
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
76107622
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
76117623

7624+
neo-async@^2.6.0:
7625+
version "2.6.2"
7626+
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
7627+
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
7628+
76127629
next-tick@~1.0.0:
76137630
version "1.0.0"
76147631
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
@@ -9248,11 +9265,24 @@ solidity-ast@^0.4.15:
92489265
resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.30.tgz#402d8277311d6680c786f756ba27e1c19f809293"
92499266
integrity sha512-3xsQIbZEPx6w7+sQokuOvk1RkMb5GIpuK0GblQDIH6IAkU4+uyJQVJIRNP+8KwhzkViwRKq0hS4zLqQNLKpxOA==
92509267

9268+
solidity-ast@^0.4.38:
9269+
version "0.4.46"
9270+
resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.46.tgz#d0745172dced937741d07464043564e35b147c59"
9271+
integrity sha512-MlPZQfPhjWXqh7YxWcBGDXaPZIfMYCOHYoLEhGDWulNwEPIQQZuB7mA9eP17CU0jY/bGR4avCEUVVpvHtT2gbA==
9272+
92519273
solidity-comments-extractor@^0.0.7:
92529274
version "0.0.7"
92539275
resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19"
92549276
integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw==
92559277

9278+
solidity-docgen@^0.6.0-beta.35:
9279+
version "0.6.0-beta.35"
9280+
resolved "https://registry.yarnpkg.com/solidity-docgen/-/solidity-docgen-0.6.0-beta.35.tgz#174d7fe54efa8b10f7d3cbe0dfc40e52e11bf867"
9281+
integrity sha512-9QdwK1THk/MWIdq1PEW/6dvtND0pUqpFTsbKwwU9YQIMYuRhH1lek9SsgnsGGYtdJ0VTrXXcVT30q20a8Y610A==
9282+
dependencies:
9283+
handlebars "^4.7.7"
9284+
solidity-ast "^0.4.38"
9285+
92569286
source-map-resolve@^0.5.0:
92579287
version "0.5.3"
92589288
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
@@ -9297,7 +9327,7 @@ source-map@^0.5.6, source-map@^0.5.7:
92979327
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
92989328
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
92999329

9300-
source-map@^0.6.0:
9330+
source-map@^0.6.0, source-map@^0.6.1:
93019331
version "0.6.1"
93029332
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
93039333
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -10030,6 +10060,11 @@ typical@^2.6.0, typical@^2.6.1:
1003010060
resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d"
1003110061
integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=
1003210062

10063+
uglify-js@^3.1.4:
10064+
version "3.17.4"
10065+
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
10066+
integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==
10067+
1003310068
ultron@~1.1.0:
1003410069
version "1.1.1"
1003510070
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
@@ -10860,6 +10895,11 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
1086010895
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
1086110896
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
1086210897

10898+
wordwrap@^1.0.0:
10899+
version "1.0.0"
10900+
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
10901+
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
10902+
1086310903
1086410904
version "6.2.1"
1086510905
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"

0 commit comments

Comments
 (0)