Skip to content

Commit

Permalink
Merge pull request galaxyproject#562 from galaxyproject/website
Browse files Browse the repository at this point in the history
IWC showcase
  • Loading branch information
mvdbeek authored Oct 11, 2024
2 parents b583eb3 + a685877 commit acb8838
Show file tree
Hide file tree
Showing 24 changed files with 14,869 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/gh-page-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Build and Deploy IWC Website

on:
push:
branches:
- main
workflow_dispatch:

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Python Dependencies
run: |
pip install -r requirements.txt
- name: Run generate_manifest.py
run: python ./scripts/workflow_manifest.py

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install NPM Dependencies
run: npm install
working-directory: ./website

- name: Build Nuxt 3 Static Site
run: npm run generate
working-directory: ./website
env:
NUXT_APP_BASE_URL: /iwc/

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./website/.output/public
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
tool_test_output.html
tool_test_output.json
.DS_Store
workflow_manifest.json
7 changes: 7 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";

// https://astro.build/config
export default defineConfig({
integrations: [tailwind()]
});
112 changes: 112 additions & 0 deletions scripts/workflow_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import os
import json
import yaml


def find_and_load_compliant_workflows(directory):
"""
Find all .dockstore.yml files in the given directory and its subdirectories.
Read the contents of these files and add the path of the file to the content.
Return a list of all collected data.
"""
workflow_data = []
for root, _, files in os.walk(directory):
if ".dockstore.yml" in files:
try:
dockstore_path = os.path.join(root, ".dockstore.yml")
with open(dockstore_path) as f:
workflow_details = yaml.safe_load(f)
workflow_details["path"] = root
workflow_data.append(workflow_details)

# Now inspect the details which are something like this:
# version: 1.2
# workflows:
# - name: Velocyto-on10X-from-bundled
# subclass: Galaxy
# publish: true
# primaryDescriptorPath: /Velocyto-on10X-from-bundled.ga
# testParameterFiles:
# - /Velocyto-on10X-from-bundled-tests.yml
# authors:
# - name: Lucille Delisle
# orcid: 0000-0002-1964-4960
# - name: Velocyto-on10X-filtered-barcodes
# subclass: Galaxy
# publish: true
# primaryDescriptorPath: /Velocyto-on10X-filtered-barcodes.ga
# testParameterFiles:
# - /Velocyto-on10X-filtered-barcodes-tests.yml
# authors:
# - name: Lucille Delisle
# orcid: 0000-0002-1964-4960

for workflow in workflow_details["workflows"]:
# For each listed workflow, load the primaryDescriptorPath
# file, which is the actual galaxy workflow.
# strip leading slash from primaryDescriptorPath if present -- these are relative.
workflow_path = os.path.join(
root, workflow["primaryDescriptorPath"].lstrip("/")
)
try:
with open(workflow_path) as f:
workflow["definition"] = json.load(f)
except Exception as e:
print(
f"No workflow file: {os.path.join(root, workflow['primaryDescriptorPath'])}: {e}"
)

# also try to load a README.md file for each workflow
try:
with open(os.path.join(root, "README.md")) as f:
workflow["readme"] = f.read()
# catch FileNotFound
except FileNotFoundError:
print(f"No README.md at {os.path.join(root, 'README.md')}")
except Exception as e:
print(
f"Error reading file {os.path.join(root, 'README.md')}: {e}"
)

# also try to load a CHANGELOG.md file for each workflow
try:
with open(os.path.join(root, "CHANGELOG.md")) as f:
workflow["changelog"] = f.read()
except FileNotFoundError:
print(f"No CHANGELOG.md at {os.path.join(root, 'CHANGELOG.md')}")
except Exception as e:
print(
f"Error reading file {os.path.join(root, 'CHANGELOG.md')}: {e}"
)
dirname = os.path.dirname(workflow_path).split("/")[-1]
workflow["trsID"] = f"#workflow/github.com/iwc-workflows/{dirname}/{workflow['name'] or 'main'}"

workflow_test_path = f"{workflow_path.rsplit('.ga', 1)[0]}-tests.yml"
if os.path.exists(workflow_test_path):
with open(workflow_test_path) as f:
tests = yaml.safe_load(f)
workflow["tests"] = tests
else:
print(f"no test for {workflow_test_path}")

except Exception as e:
print(f"Error reading file {os.path.join(root, '.dockstore.yml')}: {e}")

return workflow_data


def write_to_json(data, filename):
"""
Write the given data into a JSON file with the given filename.
"""
try:
with open(filename, "w") as f:
json.dump(data, f, indent=4)
except Exception as e:
print(f"Error writing to file {filename}: {e}")


if __name__ == "__main__":
workflow_data = find_and_load_compliant_workflows("./workflows")
write_to_json(workflow_data, "workflow_manifest.json")
24 changes: 24 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist

# Node dependencies
node_modules

# Logs
logs
*.log

# Misc
.DS_Store
.fleet
.idea

# Local env files
.env
.env.*
!.env.example
10 changes: 10 additions & 0 deletions website/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Standard ignores
**/.git
**/.svn
**/.hg
**/node_modules
# Ignore the dist folder
**/dist
# Don't reformat .json or .yml files included in the project
*.json
*.yml
83 changes: 83 additions & 0 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Nuxt 3 Minimal Starter

Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.

## Setup

Make sure to install the dependencies:

```bash
# npm
npm install

# pnpm
pnpm install

# yarn
yarn install

# bun
bun install
```

## Build workflow manifest

Build the workflow manifest file with

```bash
python scripts/workflow_manifest.py
```

## Development Server

Start the development server on `http://localhost:3000`:

```bash
# npm
npm run dev

# pnpm
pnpm run dev

# yarn
yarn dev

# bun
bun run dev
```

## Production

Build the application for production:

```bash
# npm
npm run build

# pnpm
pnpm run build

# yarn
yarn build

# bun
bun run build
```

Locally preview production build:

```bash
# npm
npm run preview

# pnpm
pnpm run preview

# yarn
yarn preview

# bun
bun run preview
```

Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
6 changes: 6 additions & 0 deletions website/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default defineAppConfig({
ui: {
primary: "amber",
gray: "neutral",
},
});
11 changes: 11 additions & 0 deletions website/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<div>
<NuxtLoadingIndicator />
<IWCHeader />
<main>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</main>
</div>
</template>
33 changes: 33 additions & 0 deletions website/components/Author.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<span class="author">
<a v-if="authorUrl !== '#'" :href="authorUrl" target="_blank" rel="noopener noreferrer" class="author-link">
{{ author.name }}
</a>
<span v-else>{{ author.name }}</span>
</span>
</template>

<script setup lang="ts">
interface Author {
name: string;
orcid?: string;
}
const props = defineProps<{
author: Author;
}>();
const authorUrl = computed(() => (props.author.orcid ? `https://orcid.org/${props.author.orcid}` : "#"));
</script>

<style scoped>
.author-link {
color: inherit;
text-decoration: none;
border-bottom: 1px dotted currentColor;
}
.author-link:hover {
border-bottom-style: solid;
}
</style>
20 changes: 20 additions & 0 deletions website/components/IWCHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<header class="shadow-md">
<UContainer class="py-4">
<div class="flex">
<div class="flex flex-grow space-x-2">
<NuxtLink to="/" class="flex items-center space-x-2">
<img src="/iwc_logo.png" alt="IWC Logo" width="64" height="64" />
<span class="text-xl font-semibold">Galaxy IWC - Workflow Library</span>
</NuxtLink>
</div>
<div class="flex items-center space-x-2">
<NuxtLink to="https://github.com/galaxyproject/iwc/">About</NuxtLink>
<NuxtLink to="https://planemo.readthedocs.io/en/latest/best_practices_workflows.html"
>Development</NuxtLink
>
</div>
</div>
</UContainer>
</header>
</template>
Loading

0 comments on commit acb8838

Please sign in to comment.