Repository navigation
337 lines (320 loc) · 14.2 KB
/
Copy pathreusable-solidity-docs.yml
File metadata and controls
337 lines (320 loc) · 14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
name: Generate and push Solidity API documentation
# To use this workflow, make sure `solidity-docgen` package is added to the
# projects's dev dependencies and is configured in Hardhat config (see
# https://github.com/OpenZeppelin/solidity-docgen#usage).
# The workflow expects `outputDir` to be set to `generated-docs`. You may
# also need to specify other configs, like `templates` or `exclude`.
on:
workflow_call:
inputs:
projectDir:
description: "A root's subfolder containing the `contracts` folder and
the Yarn / Hardhat configuration. Leave empty ('') if the project
config resides in the root. If config resides in a subfolder, provide
the subfolder name/path, without leading `.` and ending `/`. For
example, type `/v2/solidity` if the path to the `contracts` folder is
`./v2/solidity/contracts`."
type: string
required: false
default: ""
nodeVersion:
description: "Node version required by the consumer Hardhat project."
type: string
required: false
default: "22.23.1"
trimComments:
description: "True if you want to remove space characters between `///`
and a comment text in the Solidity files, before generating `.md`
files. This may be needed to improve the look of the lists in the
generated files."
type: boolean
required: false
default: true
preProcessingCommand:
description: "An optional additional bash command to be executed before
transforming the Solidity files to Markdown file(s). The command will
be executed in the path specified by `projectDir`."
type: string
required: false
addTOC:
description: "True if you want to add Table Of Contents to the generated
Markdown file. Uses `markdown-toc` tool to generate TOC. Shouldn't be
set to `true` if Docgen's `pages` attribute in `hardhat.config.ts` is
set to `items` or `files`."
type: boolean
required: false
default: true
tocOptions:
description: "Options to be passed to the `markdown-toc` tool used for
generation of Table Of Contents. See
https://github.com/jonschlinkert/markdown-toc#cli for more details."
type: string
required: false
default: "-i --maxdepth 2"
postProcessingCommand:
description: "An optional additional bash command to be executed after
transforming the Solidity files to Markdown file(s). The command will
be executed in the path specified by `projectDir`."
type: string
required: false
publish:
description: "True if you want to push the generated file(s) to the
destination repository."
type: boolean
required: false
default: true
verifyCommits:
description: "True if you want to sign commits updating the docs using
GPG key. You'll need to specify `gpgPrivateKey` and `gpgPassphrase`
secrets."
type: boolean
required: false
default: false
destinationRepo:
description: "A name of the repository where the generated Solidity docs
will be pushed to. Required if `publish=true`."
type: string
required: false
destinationFolder:
description: "A path in the destination repository where the generated
Solidity docs will be pushed to. For example, `./docs-api/tbtc-v2`."
type: string
required: false
default: "."
destinationBaseBranch:
description: "A branch on the destination repository which will be set
as a base branch of the PR updating Solidity docs (must exist)."
type: string
required: false
default: "main"
userEmail:
description: "The email address of a GitHub user associated with the
`githubToken` secret. Will be used to sign commits. Required if
`publish=true`."
type: string
required: false
userName:
description: "The name of the GitHub user associated with the
`githubToken` secret. Will be used to sign commits. Required if
`publish=true`."
type: string
required: false
rsyncDelete:
description: "True if you want to delete from the destination folder
the files which were not generated during current run of the workflow.
Usually there shouldn't be need to set this option to `true` if
Docgen's `pages` attribute in `hardhat.config.ts` is set to `single`.
In other cases the option should be use with caution."
type: boolean
required: false
default: false
commentPR:
description: "True if you want to create or update a preview comment
for this projectDir in the PR invoking the workflow. Requires
exportAsGHArtifacts=true and a token with pull-requests: write
permission. If the workflow is not triggered by the `pull_request`
event, no comment is posted. Runs for the same projectDir are not
serialized: overlapping runs can both create a comment, and
subsequent runs update the first match."
type: boolean
required: false
default: false
exportAsGHArtifacts:
description: "True if you want to see the artifacts generated on various
stages of workflow execution in the GH run details."
type: boolean
required: false
default: false
secrets:
githubToken:
description: "A GitHub API token for the destination organization.
Should have `repo` scope. Required if `publish=true`."
required: false
gpgPrivateKey:
description: "A GPG private key needed when `verifyCommits` is set to
true. See
https://github.com/crazy-max/ghaction-import-gpg#prerequisites for
instructions on key generation."
required: false
gpgPassphrase:
description: "A passphrase of the GPG key. Needed when `verifyCommits`
is set to true."
required: false
jobs:
docs-generate-html-and-publish:
runs-on: ubuntu-latest
defaults:
run:
working-directory: .${{ inputs.projectDir }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.nodeVersion }}
# Set up the toolchain before preprocessing so consumer-provided Yarn
# shims added to GITHUB_PATH keep precedence during install and docgen.
- name: Enable Corepack
shell: bash
run: corepack enable
# In this step we modify the format of the comments in the Solidity
# contracts files. We do that because our original formatting is not
# processed by Docgen in the way we would like.
# To nicely display lists (like the list of requirements) we need to
# remove multiple space chars after the `///` comment. We do that by
# executing `sed 's_///[[:blank:]]*_///_'` on all contracts files, which
# substitutes `///` + 0 or more spaces/tabs with just `///`.
- name: Prepare contract files for further processing
if: inputs.trimComments
shell: bash
run: |
find ./contracts \
-name "*.sol" \
-type f \
-exec sed -i 's_///[[:blank:]]*_///_' {} \;
- name: Execute additional command
if: inputs.preProcessingCommand != null
shell: bash
run: ${{ inputs.preProcessingCommand }}
- name: Export artifacts
if: inputs.exportAsGHArtifacts == true
uses: actions/upload-artifact@v4
with:
name: contracts-after-preprocessing
path: .${{ inputs.projectDir }}/contracts
# We may need this step in case we execute the workflow in a project
# that has a dependency to `@summa-tx/relay-sol@2.0.2` package, which
# downloads one of its sub-dependencies via unathenticated `git://`
# protocol. That protocol is no longer supported. Thanks to this step
# `https://` is used instead of `git://`.
- name: Configure git to don't use unauthenticated protocol
shell: bash
run: git config --global url."https://".insteadOf git://
- name: Install dependencies
shell: bash
env:
COREPACK_ENABLE_AUTO_PIN: "0"
run: |
yarn_version=$(yarn --version)
echo "Using Yarn $yarn_version"
if head -5 yarn.lock | grep -q "yarn lockfile v1"; then
if [[ "$yarn_version" != 1.* ]]; then
echo "::error::A Yarn Classic lockfile requires Yarn 1; found $yarn_version. Pin Yarn using packageManager, yarnPath, or preProcessingCommand."
exit 1
fi
yarn install --frozen-lockfile
elif grep -q '^__metadata:' yarn.lock; then
if [[ "$yarn_version" == 1.* ]]; then
echo "::error::A Berry lockfile requires Yarn 2 or newer; found $yarn_version. Pin Yarn using packageManager, yarnPath, or preProcessingCommand."
exit 1
fi
yarn install --immutable
else
echo "::error::A recognized yarn.lock is required for a locked dependency install."
exit 1
fi
# Generates `.md` file(s) based on config in the `hardhat.config.ts`.
- name: Build Markdown docs
run: yarn run hardhat docgen
- name: Add Table of Contents
if: inputs.addTOC == true
run: |
npm install --global markdown-toc@1.2.0
sed -i '2s/^/\<!-- toc --\> \n/' ./generated-docs/index.md
sed -i '2s/^/## Table Of Contents \n/' ./generated-docs/index.md
markdown-toc ${{ inputs.tocOptions }} ./generated-docs/index.md
- name: Execute additional command
if: inputs.postProcessingCommand != null
shell: bash
run: ${{ inputs.postProcessingCommand }}
- name: Export artifacts
if: inputs.exportAsGHArtifacts == true
uses: actions/upload-artifact@v4
with:
name: contracts-final-output
path: .${{ inputs.projectDir }}/generated-docs
- name: Post link to artifacts in PR comment
if: |
inputs.exportAsGHArtifacts == true
&& inputs.commentPR == true
&& startsWith(github.ref, 'refs/pull')
uses: actions/github-script@v8
env:
SOLIDITY_DOCS_PROJECT_DIR: ${{ inputs.projectDir }}
with:
script: |
const project = encodeURIComponent(process.env.SOLIDITY_DOCS_PROJECT_DIR || '.')
const marker = `<!-- solidity-docs-preview:${project} -->`
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
const body = `${marker}\nSolidity API documentation preview available in the artifacts of the ${runUrl} check.`
const comments = await github.paginate(github.rest.issues.listComments, {
...context.repo,
issue_number: context.issue.number,
per_page: 100
})
// The default GITHUB_TOKEN authors comments as github-actions[bot].
// Only our marker at the start of a workflow-owned comment is eligible.
const existing = comments.find(comment =>
comment.user?.login === 'github-actions[bot]' &&
comment.user?.type === 'Bot' &&
comment.body?.split('\n', 1)[0].trim() === marker
)
if (existing) {
await github.rest.issues.updateComment({
...context.repo,
comment_id: existing.id,
body
})
} else {
await github.rest.issues.createComment({
...context.repo,
issue_number: context.issue.number,
body
})
}
- name: Import GPG key
if: inputs.publish == true && inputs.verifyCommits == true
uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0
with:
gpg_private_key: ${{ secrets.gpgPrivateKey }}
passphrase: ${{ secrets.gpgPassphrase }}
git_user_signingkey: true
git_commit_gpgsign: true
- name: Sync generated docs and create PR
if: inputs.publish == true
env:
GH_TOKEN: ${{ secrets.githubToken }}
DOCS_REPO: ${{ inputs.destinationRepo }}
DOCS_FOLDER: ${{ inputs.destinationFolder }}
DOCS_BASE: ${{ inputs.destinationBaseBranch }}
DOCS_EMAIL: ${{ inputs.userEmail }}
DOCS_USER: ${{ inputs.userName }}
DOCS_DELETE: ${{ inputs.rsyncDelete }}
DOCS_SIGN: ${{ inputs.verifyCommits }}
SOURCE_RUN: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
head_branch=auto-update-solidity-api-docs
gh auth setup-git --hostname github.com
git clone --branch "$DOCS_BASE" "https://github.com/$DOCS_REPO.git" dest-repo-clone
cd dest-repo-clone
git checkout "$head_branch" || git checkout -b "$head_branch"
mkdir -p "$DOCS_FOLDER"
rsync_options=(-avh)
if [[ "$DOCS_DELETE" == true ]]; then rsync_options+=(--delete); fi
rsync "${rsync_options[@]}" ../generated-docs "$DOCS_FOLDER"
git add -A
if git diff --cached --quiet; then
echo "No documentation changes."
exit 0
fi
git config user.email "$DOCS_EMAIL"
git config user.name "$DOCS_USER"
commit_options=()
if [[ "$DOCS_SIGN" == true ]]; then commit_options+=(-S); fi
git commit "${commit_options[@]}" -m "Update docs by $SOURCE_RUN"
git push --set-upstream origin "HEAD:$head_branch"
existing_prs=$(gh pr list --repo "$DOCS_REPO" --state open --base "$DOCS_BASE" --head "$head_branch" --json number --jq length)
if [[ "$existing_prs" == 0 ]]; then
gh pr create --repo "$DOCS_REPO" --base "$DOCS_BASE" --head "$head_branch" \
--title "Update Solidity API docs" --body "Docs updated by workflow: $SOURCE_RUN"
fi