Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create flow to update subgraph docs on Dev-Portal #557

Merged
merged 8 commits into from
Apr 2, 2024
Merged
65 changes: 65 additions & 0 deletions .github/workflows/subgraph-documentation-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This workflow is triggered when a pull request is closed on the 'develop' or 'main' branches
# and there is a change to the 'packages/subgraph/schema.graphql' file.

name: Subgraph Documentation Update

on:
workflow_dispatch:
workflow_call:
push:
branches:
- develop
paths:
- 'packages/subgraph/schema.graphql'
- 'packages/subgraph/src/examples'
- '.github/workflows/subgraph-deploy.yaml'

jobs:
update_docs:
permissions: read-all
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup nodejs
uses: actions/setup-node@v4
with:
cache: 'yarn'
node-version: 16
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Generate introspection query result
run: yarn generate:introspection
working-directory: packages/subgraph/
- name: Generate Query Examples docs
run: yarn docs:examples
working-directory: packages/subgraph/
- name: Checkout developer-portal
uses: actions/checkout@v4
with:
repository: aragon/developer-portal
ref: staging
path: developer-portal
token: ${{ secrets.ARABOT_PAT }}
- name: Remove the docs/subgraph folder in the developer-portal
run: rm -rf $GITHUB_WORKSPACE/developer-portal/docs/subgraph
- name: Copy the docs/developer-portal folder to the developer-portal
run: cp -R packages/subgraph/docs/developer-portal $GITHUB_WORKSPACE/developer-portal/docs/subgraph
- name: Copy the generated schema-introspection.json to the developer-portal
run: cp -R packages/subgraph/docs/schema-introspection.json $GITHUB_WORKSPACE/developer-portal/static/subgraph
- name: Get short commit hash
id: hash
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.ARABOT_PAT }}
path: developer-portal
commit-message: 'Update the Aragon Subgraph docs by commit ${{ steps.hash.outputs.sha_short }}'
committer: 'Arabot <[email protected]>'
branch: patch/aragon-subgraph-docs
delete-branch: true
title: Update the Aragon Subgraph docs
body: 'Automated update by Github actions (Run: [${{ github.run_id }}](https://github.com/aragon/osx/actions/runs/${{ github.run_id }}))'
reviewers: ${{ github.actor }}
team-reviewers: Ara-Team-OSX
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ managementDAOTX.json
generated
subgraph.yaml
.bin
mythx.json
mythx.json
schema-introspection.json

# docs
packages/subgraph/docs/developer-portal/
5 changes: 5 additions & 0 deletions packages/subgraph/codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
generates:
./docs/schema-introspection.json:
schema: ./schema.graphql
plugins:
- introspection
7 changes: 6 additions & 1 deletion packages/subgraph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"deploy": "scripts/deploy-subgraph.sh",
"create:local": "graph create aragon/aragon-core-goerli --node http://localhost:8020",
"deploy:local": "LOCAL=true scripts/deploy-subgraph.sh",
"generate:introspection": "graphql-codegen && cd docs && prettier schema-introspection.json --write",
"docs:examples": "node ./scripts/generate-markdown.js ./src/examples && rsync -avr --prune-empty-dirs --remove-source-files --include='*/' --include='*.md' --exclude='*' ./src/examples/ ./docs/developer-portal/ --delete;",
"start:dev": "docker-compose -f docker/docker-compose.yml up -d && sleep 30 && yarn create:local && yarn deploy:local",
"stop:dev": "docker-compose -f docker/docker-compose.yml down",
"buildAndStart:dev": "docker-compose -f docker/docker-compose.yml up -d --build hardhat && sleep 30 && yarn create:local && yarn deploy:local",
Expand All @@ -30,7 +32,10 @@
"matchstick-as": "^0.5.2",
"mustache": "^4.2.0",
"ts-morph": "^17.0.1",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"graphql": "^16.8.1",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/introspection": "^4.0.3"
},
"dependencies": {
"@aragon/osx-commons-subgraph": "^0.0.4"
Expand Down
89 changes: 89 additions & 0 deletions packages/subgraph/scripts/generate-markdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
const fs = require('fs');
const glob = require('glob');
const path = require('path');

const regex = /(\/\*[ ]*MARKDOWN)(.|\n)*?(\*\/\n)/gi;
const START_REGEX = /^\/\*[ ]*MARKDOWN/i;
const END_REGEX = /\*\/\n$/;

generateMarkdown().catch(err => {
console.error(err);
process.exit(1);
});

async function generateMarkdown() {
const workingDirectory = process.argv[2];
if (!workingDirectory) {
console.error('Usage: node generate-markdown.js <working-directory>');
process.exit(1);
}
const fileList = await getFileList(workingDirectory);

for (const file of fileList) {
const basename = path.basename(file, path.extname(file));
const mdFile = path.join(path.dirname(file), basename + '.md');

const blocks = parseFile(file);
const strMarkdown = compileBlocks(blocks);
fs.writeFileSync(mdFile, strMarkdown);
}
}

function getFileList(workingDirectory) {
return glob.sync(workingDirectory + '/**/*.ts');
}

function parseFile(path) {
const str = fs.readFileSync(path).toString();
const matches = str.matchAll(regex);

let lastCursor = 0;
const blocks = [];

for (const match of matches) {
if (typeof match.index === 'undefined') continue;

// TS not catched up yet
if (lastCursor < match.index) {
blocks.push({
type: 'code',
content: str.substring(lastCursor, match.index),
});
lastCursor += match[0].length;
}
// the markdown block itself
blocks.push({type: 'markdown', content: match[0]});
lastCursor = match.index + match[0].length;
}
// remainder
if (lastCursor < str.length) {
blocks.push({
type: 'code',
content: str.substring(lastCursor, str.length),
});
}
return blocks;
}

function compileBlocks(blocks) {
let content = '';
for (const block of blocks) {
switch (block.type) {
case 'code':
content += `\n\n\`\`\`ts\n` + block.content.trim() + `\n\`\`\`\n\n\n`;
break;
case 'markdown':
content += trimMarkdownContent(block.content);
break;
default:
throw new Error('Invalid block type');
}
}
return content;
}

function trimMarkdownContent(content) {
content = content.replace(START_REGEX, '');
content = content.replace(END_REGEX, '');
return content.trim();
}
102 changes: 102 additions & 0 deletions packages/subgraph/src/examples/01-query-examples/01-dao-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* MARKDOWN
---
title: DAO Query [WIP]
sidebar_label: DAO Query
---

## DAO Query

The query
*/
import {gql} from 'graphql-request';

export const QueryDao = gql`
query Dao($address: ID!) {
dao(id: $address) {
id
subdomain
metadata
createdAt
plugins {
appliedPreparation {
pluginAddress
}
appliedPluginRepo {
subdomain
}
appliedVersion {
build
release {
release
}
}
}
}
}
`;

export const QueryDaos = gql`
query Daos(
$limit: Int!
$skip: Int!
$direction: OrderDirection!
$sortBy: Dao_orderBy!
) {
daos(
first: $limit
skip: $skip
orderDirection: $direction
orderBy: $sortBy
) {
id
subdomain
metadata
plugins {
appliedPreparation {
pluginAddress
}
appliedPluginRepo {
subdomain
}
appliedVersion {
build
release {
release
}
}
}
}
}
`;

/* MARKDOWN
The return

```json
{
"data": {
"dao": {
"id": "0x02bbc496bebc9a06c239670cea663c43cead899f",
"subdomain": "test",
"metadata": "ipfs://QmVGCibCLPgqA8eszxQJMzQFcmQAdrkyhTGH6EB5ERivsR",
"createdAt": "1677584087",
"plugins": [
{
"appliedPreparation": {
"pluginAddress": "0x404f4bbd06e3a42c70297633e440b11bb083d482"
},
"appliedPluginRepo": {
"subdomain": "multisig"
},
"appliedVersion": {
"build": 1,
"release": {
"release": 1
}
}
}
]
}
}
}
*/
102 changes: 102 additions & 0 deletions packages/subgraph/src/examples/01-query-examples/02-balances-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* MARKDOWN
---
title: Balances Query [WIP]
sidebar_label: Balances Query
---

## Balances Query

The query
*/
import {gql} from 'graphql-request';

export const QueryTokenBalances = gql`
query TokenBalances(
$where: TokenBalance_filter!
$limit: Int!
$skip: Int!
$direction: OrderDirection!
$sortBy: TokenBalance_orderBy!
) {
tokenBalances(
where: $where
first: $limit
skip: $skip
orderDirection: $direction
orderBy: $sortBy
) {
lastUpdated
__typename
... on ERC20Balance {
balance
token {
name
decimals
symbol
id
}
}
... on ERC721Balance {
token {
name
symbol
id
}
tokenIds
}
... on NativeBalance {
balance
}
... on ERC1155Balance {
metadataUri
token {
id
}
balances {
amount
id
tokenId
}
}
}
}
`;

/* MARKDOWN
The return

```json
{
"data": {
"tokenBalances": [
{
"lastUpdated": "1682856167",
"__typename": "ERC20Balance",
"balance": "308999000000000004456448",
"token": {
"name": "VEGAHVB",
"decimals": 18,
"symbol": "VGH",
"id": "0x63677b9f25431e361f15019637533b4228cdc3ef"
}
},
{
"lastUpdated": "1682856587",
"__typename": "ERC20Balance",
"balance": "499999999999999991611392",
"token": {
"name": "42K",
"decimals": 18,
"symbol": "42K",
"id": "0x7604fb940b31c988405847cc2db7a90938b529fc"
}
},
{
"lastUpdated": "1697108195",
"__typename": "NativeBalance",
"balance": "2010000000000000"
}
]
}
}
*/
Loading
Loading