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

feat: add dev gateways with dashboards #116

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/test-dev-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Test Dev (e2e)

on:
workflow_dispatch:
push:
branches:
- main
pull_request:

jobs:
bifrost-gateway:
uses: singulargarden/bifrost-gateway2/.github/workflows/gateway-conformance.yml@main
with:
artifact_json_name: conformance-bifrost-gateway.json
kubo-gateway:
uses: singulargarden/kubo/.github/workflows/gateway-conformance.yml@master
with:
artifact_json_name: conformance-kubo-gateway.json
aggregate:
runs-on: "ubuntu-latest"
needs: [bifrost-gateway, kubo-gateway]
# the tests might have failed
if: always()
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
with:
path: "gateway-conformance"
- name: Download Artifacts
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Aggregate results
working-directory: ./artifacts
run: |
set -e
set -o pipefail
mkdir ./aggregates

# download-artifact downloads artifacts in a directory named after the artifact
# details: https://github.com/actions/download-artifact#download-all-artifacts
for folder in ./conformance-*.json; do
file="${folder}/output.json"
new_file="aggregates/${folder#conformance-}"
jq -ns 'inputs' "$file" | node ../gateway-conformance/aggregate.js 1 > "${new_file}"
done

node ../gateway-conformance/aggregate-into-table.js ./aggregates/*.json > /tmp/table.md
node ../gateway-conformance/aggregate-update-names.js ../gateway-conformance/names.json /tmp/table.md > ./table.md
- name: Set summary
if: (failure() || success())
run: cat ./artifacts/table.md >> $GITHUB_STEP_SUMMARY
1 change: 1 addition & 0 deletions .github/workflows/test-prod-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ jobs:
done
node ../gateway-conformance/aggregate-into-table.js ./aggregates/*.json > ./table.md
node ../gateway-conformance/aggregate-update-names.js ../gateway-conformance/names.json ./table.md > ./table.md
- name: Set summary
if: (failure() || success())
run: cat ./artifacts/table.md >> $GITHUB_STEP_SUMMARY
75 changes: 51 additions & 24 deletions .github/workflows/update-badge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
workflow_run:
workflows:
- Test Production (e2e)
- Test Dev (e2e)
types:
- completed
branches:
Expand All @@ -23,41 +24,67 @@ concurrency:
cancel-in-progress: true

jobs:
update-badge:
update-badge-prod:
runs-on: ubuntu-latest
steps:
- uses: pl-strflt/job-summary-url-action@v1
id: metadata
with:
workflow: test-prod-e2e.yml # ${{ github.event.workflow.path }}
workflow: ${{ github.event.workflow.path }}
run_id: ${{ github.event.workflow_run.id }}
run_attempt: ${{ github.event.workflow_run.run_attempt }}
job: aggregate
- uses: actions/checkout@v3
- id: update
uses: actions/github-script@v6
env:
WORKFLOW_PATH: ${{ github.event.workflow.path }}
BADGE_URL: ${{ github.event.workflow.badge_url }}
SUMMARY_URL: ${{ steps.metadata.outputs.job_summary_url }}
with:
script: |
const fs = require('fs')

const workflowPath = process.env.WORKFLOW_PATH
const badgeURL = process.env.BADGE_URL
const refName = process.env.GITHUB_REF_NAME
const summaryURL = process.env.SUMMARY_URL

console.log(`
workflowPath: ${workflowPath}
badgeURL: ${badgeURL}
refName: ${refName}
summaryURL: ${summaryURL}
`)

function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const searchValue = new RegExp(`\\[!\\[([^\\]]+)\\]\\(.*${escapeRegExp(badgeURL)}.*\\)\\]\\(.*\\)`, 'g')
const replaceValue = `[![$1](${badgeURL}?branch=${refName})](${summaryURL})`

console.log(`Searching for: ${searchValue}`)
console.log(`To replace it with: ${replaceValue}`)

const readme = fs.readFileSync('README.md').toString()
const updatedReadme = readme.replace(searchValue, replaceValue)

if (readme !== updatedReadme) {
console.log('Updating README')
fs.writeFileSync('README.md', updatedReadme)
return true
} else {
console.log('README does not need to be updated')
return false
}
# https://github.com/orgs/community/discussions/26560
- run: |
- if: steps.update.outputs.result == 'true'
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
- run: |
echo GITHUB_JOB_SUMMARY_URL=${GITHUB_JOB_SUMMARY_URL}
IN='[![Conformance Production Dashboard](https://github.com/ipfs/gateway-conformance/actions/workflows/test-prod-e2e.yml/badge.svg?branch=master)](.*)'
ESCAPED_IN=$(printf '%s\n' "$IN" | sed -e 's/[][\/!&]/\\&/g')

OUT="[![Conformance Production Dashboard](https://github.com/ipfs/gateway-conformance/actions/workflows/test-prod-e2e.yml/badge.svg?branch=master)](${GITHUB_JOB_SUMMARY_URL})"

sed -i "s;${ESCAPED_IN};${OUT};" README.md
env:
GITHUB_JOB_SUMMARY_URL: ${{ steps.metadata.outputs.job_summary_url }}
REPOSITORY: ${{ github.repository }}
- id: git
run: |
if [[ -n $(git diff --shortstat 2> /dev/null | tail -n1) ]]; then
echo "dirty=1" >> $GITHUB_OUTPUT
else
echo "dirty=0" >> $GITHUB_OUTPUT
fi
- if: steps.git.outputs.dirty == '1'
- if: steps.update.outputs.result == 'true'
run: |
git add README.md
git commit -m 'chore: update the link to the dashboard [skip ci]'
git push
git commit -m 'chore: update the link to the interop dashboard [skip ci]'
git push
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

`gateway-conformance` is a tool designed to test if an IPFS Gateway implementation complies with the IPFS Gateway Specification correctly. The tool is distributed as a Docker image, as well as a GitHub Action(s).

[![Conformance Production Dashboard](https://github.com/ipfs/gateway-conformance/actions/workflows/test-prod-e2e.yml/badge.svg?branch=master)]()
[![Conformance Production Dashboard](https://github.com/singulargarden/gateway-conformance/workflows/Test%20Dev%20(e2e)/badge.svg?branch=main)]()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than "Production" and "Dev" maybe use...

Gateway Instance Conformance Dashboard
Gateway Implementation Conformance Dashboard

Dev and Prod sounds like one is "development/preproduction" and one is "production".


[![Conformance Dev Dashboard](https://github.com/singulargarden/gateway-conformance/workflows/Test%20Production%20(e2e)/badge.svg?branch=main)]()

## Table of Contents

Expand Down
27 changes: 27 additions & 0 deletions aggregate-update-names.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const fs = require('fs');

const jsonFilePath = process.argv[2];
const markdownFilePath = process.argv[3];

// Check if file paths are provided
if (!jsonFilePath || !markdownFilePath) {
console.error('Both a JSON file path and a Markdown file path must be provided.');
process.exit(1);
}

const jsonData = JSON.parse(fs.readFileSync(jsonFilePath, 'utf8'));
const sortedKeys = Object.keys(jsonData).sort((a, b) => b.length - a.length);

let markdown = fs.readFileSync(markdownFilePath, 'utf8');

for (const key of sortedKeys) {
const newName = jsonData[key][1]
? `[${jsonData[key][0]}](${jsonData[key][1]})`
: jsonData[key][0];

const regex = new RegExp(key, 'g');
markdown = markdown.replace(regex, newName);
}

// output the new markdown to stdout
fs.writeFileSync(1, markdown);
122 changes: 122 additions & 0 deletions names.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ keeping this file in sync with test function names will be a challenge.

We need either:

  • error CI on missing entry (so we don't miss updating this file when we rename a func, or add new one)
  • replace this JSON with some golang convention (godoc, or maybe additional strings passed to each test), so these strings and URLs live in the same file as tests (+error CI when empty)

Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"Cors": [
"Cross-Origin Resource Sharing",
null
],
"DAgPbConversion": [
"DAG Protobuf Conversion",
null
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
],
"DNSLinkGateway": [
"DNS Link Gateway",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"https://specs.ipfs.tech/http-gateways/dnslink-gateway/"
],
"DNSLinkGatewayUnixFSDirectoryListing": [
"DNS Link Gateway Unix FS Directory Listing",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"https://specs.ipfs.tech/http-gateways/dnslink-gateway/"
],
"GatewayBlock": [
"Gateway Block",
null
],
"GatewayCache": [
"Gateway Cache",
null
],
"GatewayCacheWithIPNS": [
"Gateway Cache with IPNS",
null
],
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"GatewayIPNSRecord": [
"Gateway IPNS Record",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"GatewayJSONCborAndIPNS": [
"Gateway JSON CBOR and IPNS",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"GatewayJsonCbor": [
"Gateway JSON CBOR",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
],
"GatewaySubdomainAndIPNS": [
"Gateway Subdomain and IPNS",
null
],
"GatewaySubdomains": [
"Gateway Subdomains",
null
],
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"GatewaySymlink": [
"Gateway Symbolic Link",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"NativeDag": [
"Native DAG",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"Pathing": [
"Pathing",
null
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
],
"PlainCodec": [
"Plain Codec",
null
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
],
"RedirectsFileSupport": [
"Redirects File Support",
"https://specs.ipfs.tech/http-gateways/web-redirects-file/"
],
"RedirectsFileSupportWithDNSLink": [
"Redirects File Support with DNS Link",
"https://specs.ipfs.tech/http-gateways/web-redirects-file/"
],
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"SubdomainGatewayDNSLinkInlining": [
"Subdomain Gateway DNS Link Inlining",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
],
"Tar": [
"Tar",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"TrustlessCarDagScopeAll": [
"Trustless Car DAG Scope All",
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
"TrustlessCarDagScopeBlock": [
"Trustless Car DAG Scope Block",
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
"TrustlessCarDagScopeEntity": [
"Trustless Car DAG Scope Entity",
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
"TrustlessCarEntityBytes": [
"Trustless Car Entity Bytes",
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
"TrustlessCarPathing": [
"Trustless Car Pathing",
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"TrustlessRaw": [
"Trustless Raw",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"https://specs.ipfs.tech/http-gateways/trustless-gateway/"
],
"UnixFSDirectoryListing": [
"Unix FS Directory Listing",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"UnixFSDirectoryListingOnSubdomainGateway": [
"Unix FS Directory Listing on Subdomain Gateway",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
null
],
"conformance-bifrost-gateway": [
"Bifrost Gateway",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"https://github.com/ipfs/bifrost-gateway"
],
"conformance-kubo-gateway": [
"Kubo Gateway",
laurentsenta marked this conversation as resolved.
Show resolved Hide resolved
"https://github.com/ipfs/kubo"
]
}
Loading