Skip to content

Commit

Permalink
Merge pull request #179 from ipfs/feat-documentation
Browse files Browse the repository at this point in the history
Complete Documentation
  • Loading branch information
laurentsenta authored Nov 20, 2023
2 parents 0775864 + 37308bb commit 4ef1b99
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
with:
context: .
build-args: |
VERSION:${{ needs.release.outputs.tag }}
VERSION=${{ needs.release.outputs.tag }}
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.tags.outputs.tags }}
60 changes: 34 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
> A tool designed to test if an IPFS Gateway implementation complies with the [IPFS Gateway Specification](https://specs.ipfs.tech/http-gateways/) correctly.
> Distributed as a Docker image, as well as a GitHub Action(s).
- [Dashboard](#dashboard)
- [Commands](#commands)
- [`test`](#test)
- [Inputs](#inputs)
Expand All @@ -17,12 +18,42 @@
- [Local Development](#local-development)
- [Examples](#examples)
- [APIs](#apis)
- [Dashboard](#dashboard)
- [Adding your gateway to the dashboard](#adding-your-gateway-to-the-dashboard)
- [Building the Dashboard](#building-the-dashboard)
- [FAQ](#faq)
- [In Development](#in-development)

## Dashboard

The [Implementation Dashboard](https://ipfs.github.io/gateway-conformance/) is a view that showcases different implementations of IPFS Gateways. This dashboard aggregates results from many test runs and renders them on a static website. This'll give you more detailed insights and navigation options.

### How it Works

For every implementations that have been added to the `REPOSITORIES` file, our dashboard generation workflow loads the most recent `gateway-conformance` test results from their CI. You can try this locally with the `make website` command.

### Adding your gateway to the dashboard

The dashboard is hosted at [conformance.ipfs.tech](https://conformance.ipfs.tech/). It aggregates test outputs from various IPFS implementations and renders them on a static website.

To add your gateway to the dashboard, you need to:

- Ensure that your gateway's repository is public.
- Ensure your gateway generates generates the `output.json` file in a `gateway-conformance.yml` file. Check [kubo's workflow](https://github.com/ipfs/kubo/blob/master/.github/workflows/gateway-conformance.yml) for an example.
- Add your gateway to the list of repositories in the [REPOSITORIES](./REPOSITORIES) file.

Once you join the dashboard, your test results will be picked up automatically and your implementation will show up on the dashboard.

### Building the Dashboard

- Set up a GitHub Token: Ensure you have a GitHub Token with `repo:read` scope. This is required to download artifacts.
- Run the Build Command: `GH_TOKEN=your_github_token make website`

This command downloads the latest test artifacts from the repositories listed in the `./REPOSITORIES` file. Then it generates a static website with Hugo in the `www/public` directory.

### How to work on the Dashboard

- Use `make website` to generate all the assets required to build the static dashboard
- Use `cd ./www && hugo server` to start a local server with live-reload
- Use `cd ./www/themes/conformance && npm run build` to re-build the theme's styles

## Commands

### test
Expand Down Expand Up @@ -304,29 +335,6 @@ This templating is used almost everywhere in the test sugar, for example in requ
Request().Path("ipfs/{{cid}}", myCid) // will use "ipfs/Qm...."
```

## Dashboard

The gateway conformance test suite includes a web dashboard. This dashboard aggregates results from many test runs and renders them on a static website. This'll give you more detailed insights and navigation options.

### Adding your gateway to the dashboard

The dashboard is hosted at [conformance.ipfs.tech](https://conformance.ipfs.tech/). It aggregates test outputs from various IPFS implementations and renders them on a static website.

To add your gateway to the dashboard, you need to:

- Ensure that your gateway's repository is public.
- Ensure your gateway generates generates the `output.json` file in a `gateway-conformance.yml` file. Check [kubo's workflow](https://github.com/ipfs/kubo/blob/master/.github/workflows/gateway-conformance.yml) for an example.
- Add your gateway to the list of repositories in the [REPOSITORIES](./REPOSITORIES) file.

Once you join the dashboard, your test results will be picked up automatically and your implementation will show up on the dashboard.

### Building the Dashboard

- Set up a GitHub Token: Ensure you have a GitHub Token with `repo:read` scope. This is required to download artifacts.
- Run the Build Command: `GH_TOKEN=your_github_token make website`

This command downloads the latest test artifacts from the repositories listed in the `./REPOSITORIES` file. Then it generates a static website with Hugo in the `www/public` directory.

## FAQ

### How to generate XML, HTML and Markdown reports when using the tool as a Docker container?
Expand Down
34 changes: 33 additions & 1 deletion munge_aggregates.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ const computeName = (u) => {
};
};

const getTestRunDetails = async (jobUrl) => {
if (!jobUrl) {
return {};
}

const match = jobUrl.match(/https:\/\/github\.com\/([^\/]+)\/([^\/]+)\/actions\/runs\/(\d+)/);
if (!match) {
console.warn('Invalid URL format:', jobUrl);
return {};
}

const [, owner, repo, run_id] = match;

const apiUrl = `https://api.github.com/repos/${owner}/${repo}/actions/runs/${run_id}`;

try {
// Required node18
const result = await fetch(apiUrl, {
headers: {
'Accept': 'application/vnd.github.v3+json'
}
})
const { created_at, head_sha, head_branch, run_started_at } = await result.json()
return { created_at, head_sha, head_branch, run_started_at }
} catch (e) {
console.error(`Error fetch ${jobUrl} details:`, e);
return {}
}
}

const main = async () => {
let db = new sqlite3.Database(dbFile, (err) => {
if (err) {
Expand All @@ -86,7 +116,9 @@ const main = async () => {
if (!runs[id]) {
runs[id] = {};
}
runs[id][version] = rest;
const testRunDetails = await getTestRunDetails(rest.job_url);

runs[id][version] = { ...rest, ...testRunDetails };
}
outputJSON("data/testruns.json", runs);

Expand Down
48 changes: 31 additions & 17 deletions www/themes/conformance/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -788,11 +788,6 @@ video {
margin-bottom: 1.5rem;
}

.my-auto {
margin-top: auto;
margin-bottom: auto;
}

.mb-3 {
margin-bottom: 0.75rem;
}
Expand All @@ -801,8 +796,8 @@ video {
margin-bottom: 1rem;
}

.ml-4 {
margin-left: 1rem;
.mb-6 {
margin-bottom: 1.5rem;
}

.mr-2 {
Expand Down Expand Up @@ -873,10 +868,18 @@ video {
width: 1.25rem;
}

.w-8 {
width: 2rem;
}

.w-auto {
width: auto;
}

.w-full {
width: 100%;
}

.min-w-full {
min-width: 100%;
}
Expand All @@ -901,10 +904,6 @@ video {
grid-template-columns: repeat(1, minmax(0, 1fr));
}

.flex-col {
flex-direction: column;
}

.items-center {
align-items: center;
}
Expand All @@ -927,12 +926,6 @@ video {
column-gap: 1.5rem;
}

.space-x-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(1rem * var(--tw-space-x-reverse));
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
}

.divide-y > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
Expand Down Expand Up @@ -1065,10 +1058,22 @@ video {
padding-bottom: 0.5rem;
}

.pb-4 {
padding-bottom: 1rem;
}

.pr-4 {
padding-right: 1rem;
}

.pt-1 {
padding-top: 0.25rem;
}

.text-left {
text-align: left;
}

.text-center {
text-align: center;
}
Expand Down Expand Up @@ -1124,6 +1129,11 @@ video {
color: rgb(59 130 246 / var(--tw-text-opacity));
}

.text-blue-600 {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity));
}

.text-blue-700 {
--tw-text-opacity: 1;
color: rgb(29 78 216 / var(--tw-text-opacity));
Expand Down Expand Up @@ -1444,6 +1454,10 @@ article th {
color: rgb(55 65 81 / var(--tw-text-opacity));
}

.hover\:underline:hover {
text-decoration-line: underline;
}

@media (min-width: 640px) {
.sm\:px-6 {
padding-left: 1.5rem;
Expand Down
32 changes: 11 additions & 21 deletions www/themes/conformance/layouts/partials/breadcrumbs.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
{{ define "breadcrumbitem" }}
<li>
<div class="flex items-center">
{{ if (gt (len .Ancestors) 0) }}
<svg
class="h-5 w-5 flex-shrink-0 text-gray-300"
fill="currentColor"
viewBox="0 0 20 20"
aria-hidden="true"
class="h-8 w-8 flex-shrink-0 text-gray-300 px-1 pt-1 pb-2"
fill="currentColor"
viewBox="0 0 20 20"
aria-hidden="true"
>
<path d="M5.555 17.776l8-16 .894.448-8 16-.894-.448z" />
</svg>
<a
href="{{ .RelPermalink }}"
class="ml-4 text-sm font-medium text-gray-500 hover:text-gray-700"
class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 pb-2 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700"
aria-current="page"
>{{ .Title }}</a
>
{{ else }}
<a href="{{ .RelPermalink }}" class="text-gray-400 hover:text-gray-500">
{{/* <a href="{{ .RelPermalink }}" class="text-gray-400 hover:text-gray-500">
<svg
class="h-5 w-5 flex-shrink-0"
viewBox="0 0 20 20"
Expand All @@ -31,19 +29,11 @@
/>
</svg>
<span class="sr-only">{{ .Title }}</span>
</a>
</a> */}}
{{ end }}
</div>
</li>
{{ end }}

<div class="flex flex-col my-auto items-center">
<nav class="flex" aria-label="Breadcrumb">
<ol role="list" class="flex items-center space-x-4">
{{- range $i, $p := .Ancestors.Reverse }}
{{ template "breadcrumbitem" $p }}
{{ end }}
{{ template "breadcrumbitem" . }}
</ol>
</nav>
</div>
{{- range $i, $p := .Ancestors.Reverse }}
{{ template "breadcrumbitem" $p }}
{{ end }}
{{ template "breadcrumbitem" . }}
6 changes: 5 additions & 1 deletion www/themes/conformance/layouts/partials/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
<a class="flex items-center gap-x-2" href="{{ "" | relLangURL}}" class="-m-1.5 p-1.5">
<img class="h-8 w-auto" src="{{ absURL "logo.png" }}" alt="Logo">
</a>
{{ if .Site.Menus.main }}
{{ if .Site.Menus.main }}
{{ $currentPage := . }}
{{ range .Site.Menus.main }}
<a class="inline-flex items-center border-b-2 border-transparent px-1 pt-1 pb-2 text-sm font-medium text-white-specs hover:border-gray-300 hover:text-gray-300 {{ if $currentPage.IsMenuCurrent "main" . }} border-gray-300 text-gray-300{{ end }}" href="{{ .URL }}" title="{{ .Name }} page">
{{ .Name }}
</a>
{{ end }}
{{ end }}

{{- block "breadcrumbs" . }}
{{ partial "breadcrumbs.html" . }}
{{- end -}}
</div>
</nav>
</header>
2 changes: 1 addition & 1 deletion www/themes/conformance/layouts/partials/result-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,4 @@
</tr>
{{ end }}
</tbody>
</table>
</table>
37 changes: 36 additions & 1 deletion www/themes/conformance/layouts/results/term.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,41 @@ <h2>{{.Title}}</h2>
{{.TableOfContents}}

{{.Content}}
<div class="w-full mx-auto">
{{ $implem := .Params.implementation_id }}
{{ $requestedVersion := .Params.version }}

{{ with (index site.Data "testruns" .Params.implementation_id ) }}
{{ range $version, $details := . }}
{{ if (or (eq $requestedVersion nil) (eq $requestedVersion $version)) }}
<div class="mb-6 pb-4">
<h2 class="text-xl font-semibold mb-4">Metadata</h2>
<table class="w-full text-left">
<tr>
<td class="font-medium pr-4 py-2">Conformance Version:</td>
<td class="py-2">{{ $version }}</td>
</tr>
<tr>
<td class="font-medium pr-4 py-2">Implementation Version:</td>
<td class="py-2">{{ $details.head_branch }} ({{ $details.head_sha }})</td>
</tr>
<tr>
<td class="font-medium pr-4 py-2">Results Generated At:</td>
<td class="py-2">{{ $details.created_at }}</td>
</tr>
<tr>
<td class="font-medium pr-4 py-2">Job URL:</td>
<td class="py-2"><a href="{{ $details.job_url }}" class="text-blue-600 hover:underline">{{ $details.job_url }}</a></td>
</tr>
</table>
</div>
{{ end }}
{{ end }}
{{ end }}
</div>

<h2 class="text-xl font-semibold mb-4">Results</h2>

<div class="p-4 bg-white shadow-md rounded-lg">
{{ partial "result-table.html" .Params }}
</div>
Expand Down Expand Up @@ -50,4 +85,4 @@ <h3>See Also</h3>
<li><a href="{{.RelPermalink}}">{{.Title}}</a></li>
{{end}}
</ul>
{{end}} {{end}}
{{end}} {{end}}

0 comments on commit 4ef1b99

Please sign in to comment.