Add preview on PRs (#274)
This commit is contained in:
78
.github/preview.mjs
vendored
Normal file
78
.github/preview.mjs
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
//Imports
|
||||
import fs from "fs/promises"
|
||||
import paths from "path"
|
||||
import url from "url"
|
||||
import setup from "../source/app/metrics/setup.mjs"
|
||||
|
||||
//Paths
|
||||
const __metrics = paths.join(paths.dirname(url.fileURLToPath(import.meta.url)), "..")
|
||||
const __templates = paths.join(paths.join(__metrics, "source/templates/"))
|
||||
const __node_modules = paths.join(paths.join(__metrics, "node_modules"))
|
||||
const __web = paths.join(paths.join(__metrics, "source/app/web/statics"))
|
||||
const __web_about = paths.join(paths.join(__web, "about"))
|
||||
|
||||
const __preview = paths.join(paths.join(__web, "preview"))
|
||||
const __preview_js = paths.join(__preview, ".js")
|
||||
const __preview_css = paths.join(__preview, ".css")
|
||||
const __preview_templates = paths.join(__preview, ".templates")
|
||||
const __preview_templates_ = paths.join(__preview, ".templates_")
|
||||
const __preview_about = paths.join(__preview, "about/.statics")
|
||||
|
||||
//Extract from web server
|
||||
const {conf, Templates} = await setup({nosettings:true, log:false})
|
||||
const templates = Object.entries(Templates).map(([name]) => ({name, enabled:true}))
|
||||
const metadata = Object.fromEntries(Object.entries(conf.metadata.plugins)
|
||||
.map(([key, value]) => [key, Object.fromEntries(Object.entries(value).filter(([key]) => ["name", "icon", "categorie", "web", "supports"].includes(key)))])
|
||||
.map(([key, value]) => [key, key === "core" ? {...value, web:Object.fromEntries(Object.entries(value.web).filter(([key]) => /^config[.]/.test(key)).map(([key, value]) => [key.replace(/^config[.]/, ""), value]))} : value]))
|
||||
|
||||
|
||||
//Directories
|
||||
await fs.mkdir(__preview, {recursive:true})
|
||||
await fs.mkdir(__preview_js, {recursive:true})
|
||||
await fs.mkdir(__preview_css, {recursive:true})
|
||||
await fs.mkdir(__preview_templates, {recursive:true})
|
||||
await fs.mkdir(__preview_templates_, {recursive:true})
|
||||
await fs.mkdir(__preview_about, {recursive:true})
|
||||
|
||||
//Web
|
||||
fs.copyFile(paths.join(__web, "index.html"), paths.join(__preview, "index.html"))
|
||||
fs.copyFile(paths.join(__web, "favicon.png"), paths.join(__preview, ".favicon.png"))
|
||||
fs.copyFile(paths.join(__web, "opengraph.png"), paths.join(__preview, ".opengraph.png"))
|
||||
//Plugins and templates
|
||||
fs.writeFile(paths.join(__preview, ".plugins"), JSON.stringify(Object.entries(metadata).filter(([_name, {categorie}]) => categorie !== "core").map(([name]) => ({name, enabled:false}))))
|
||||
fs.writeFile(paths.join(__preview, ".plugins.base"), JSON.stringify(conf.settings.plugins.base.parts))
|
||||
fs.writeFile(paths.join(__preview, ".plugins.metadata"), JSON.stringify(metadata))
|
||||
fs.writeFile(paths.join(__preview, ".templates__"), JSON.stringify(templates))
|
||||
for (const template in conf.templates) {
|
||||
fs.writeFile(paths.join(__preview_templates_, template), JSON.stringify(conf.templates[template]))
|
||||
const __partials = paths.join(__templates, template, "partials")
|
||||
const __preview_partials = paths.join(__preview_templates, template, "partials")
|
||||
await fs.mkdir(__preview_partials, {recursive:true})
|
||||
for (const file of await fs.readdir(__partials))
|
||||
fs.copyFile(paths.join(__partials, file), paths.join(__preview_partials, file))
|
||||
}
|
||||
//Styles
|
||||
fs.copyFile(paths.join(__web, "style.css"), paths.join(__preview_css, "style.css"))
|
||||
fs.copyFile(paths.join(__web, "style.vars.css"), paths.join(__preview_css, "style.vars.css"))
|
||||
fs.copyFile(paths.join(__node_modules, "prismjs/themes/prism-tomorrow.css"), paths.join(__preview_css, "style.prism.css"))
|
||||
//Scripts
|
||||
fs.writeFile(paths.join(__preview_js, "app.js"), `${await fs.readFile(paths.join(__web, "app.js"))}`)
|
||||
fs.writeFile(paths.join(__preview_js, "app.placeholder.js"), `${await fs.readFile(paths.join(__web, "app.placeholder.js"))}`)
|
||||
fs.copyFile(paths.join(__node_modules, "ejs/ejs.min.js"), paths.join(__preview_js, "ejs.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "faker/dist/faker.min.js"), paths.join(__preview_js, "faker.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "axios/dist/axios.min.js"), paths.join(__preview_js, "axios.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "axios/dist/axios.min.map"), paths.join(__preview_js, "axios.min.map"))
|
||||
fs.copyFile(paths.join(__node_modules, "vue/dist/vue.min.js"), paths.join(__preview_js, "vue.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "vue-prism-component/dist/vue-prism-component.min.js"), paths.join(__preview_js, "vue.prism.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "vue-prism-component/dist/vue-prism-component.min.js.map"), paths.join(__preview_js, "vue-prism-component.min.js.map"))
|
||||
fs.copyFile(paths.join(__node_modules, "prismjs/prism.js"), paths.join(__preview_js, "prism.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "prismjs/components/prism-yaml.min.js"), paths.join(__preview_js, "prism.yaml.min.js"))
|
||||
fs.copyFile(paths.join(__node_modules, "prismjs/components/prism-markdown.min.js"), paths.join(__preview_js, "prism.markdown.min.js"))
|
||||
//Meta
|
||||
fs.writeFile(paths.join(__preview, ".version"), JSON.stringify(`${conf.package.version}-preview`))
|
||||
fs.writeFile(paths.join(__preview, ".hosted"), JSON.stringify({by:"metrics", link:"https://github.com/lowlighter/metrics"}))
|
||||
//About
|
||||
fs.copyFile(paths.join(__web, "about", "index.html"), paths.join(__preview, "about", "index.html"))
|
||||
for (const file of await fs.readdir(__web_about))
|
||||
if (file !== ".statics")
|
||||
fs.copyFile(paths.join(__web_about, file), paths.join(__preview_about, file))
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -108,4 +108,7 @@ settings.json
|
||||
|
||||
# Community templates
|
||||
source/templates/.community
|
||||
source/templates/@*
|
||||
source/templates/@*
|
||||
|
||||
# Preview
|
||||
source/app/web/statics/preview
|
||||
@@ -8,6 +8,7 @@
|
||||
"test": "jest --runInBand",
|
||||
"index": "node .github/index.mjs",
|
||||
"quickstart": "node .github/quickstart/index.mjs",
|
||||
"preview": "node .github/preview.mjs",
|
||||
"linter": "eslint source/**/*.mjs",
|
||||
"dev": "nodemon source/app/web/index.mjs -e mjs,css,ejs,json",
|
||||
"postinstall": "node node_modules/puppeteer/install.js"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M11.5 7a4.499 4.499 0 11-8.998 0A4.499 4.499 0 0111.5 7zm-.82 4.74a6 6 0 111.06-1.06l3.04 3.04a.75.75 0 11-1.06 1.06l-3.04-3.04z"></path></svg>
|
||||
Search a GitHub user
|
||||
</h2>
|
||||
<small>{{ requests.remaining }} GitHub requests remaining</small>
|
||||
<small :class="{'error-text':!requests.remaining}">{{ requests.remaining }} GitHub requests remaining</small>
|
||||
<small>Send feedback on <a href="https://github.com/lowlighter/metrics/discussions/229" target="_blank">GitHub discussions</a>!</small>
|
||||
</div>
|
||||
<div class="inputs">
|
||||
@@ -58,6 +58,10 @@
|
||||
An error occurred while generating metrics :(<br>
|
||||
<small>{{ error.message }}</small>
|
||||
</div>
|
||||
<small class="warning" v-if="preview">
|
||||
Metrics insights are rendered by <a href="https://metrics.lecoq.io/">metrics.lecoq.io</a> in preview mode.<br>
|
||||
Any backend editions won't be reflected but client-side rendering can still be tested.
|
||||
</small>
|
||||
</section>
|
||||
|
||||
<template v-if="metrics">
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
url() {
|
||||
return `${window.location.protocol}//${window.location.host}/about/${this.user}`
|
||||
},
|
||||
preview() {
|
||||
return /-preview$/.test(this.version)
|
||||
}
|
||||
},
|
||||
//Data initialization
|
||||
data:{
|
||||
|
||||
@@ -207,6 +207,10 @@
|
||||
//Return object
|
||||
const configure = Object.fromEntries(entries)
|
||||
return Object.keys(configure).length ? configure : null
|
||||
},
|
||||
//Is in preview mode
|
||||
preview() {
|
||||
return /-preview$/.test(this.version)
|
||||
}
|
||||
},
|
||||
//Methods
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
|
||||
<div class="ui-avatar" :style="{backgroundImage:avatar ? `url(${avatar})` : 'none'}"></div>
|
||||
|
||||
<input type="text" v-model="user" placeholder="Your GitHub username" :disabled="generated.pending" @keyup.enter="(!user)||(generated.pending)||(unusable.length > 0) ? null : generate()">
|
||||
<button @click="generate" :disabled="(!user)||(generated.pending)||(unusable.length > 0)">
|
||||
<input type="text" v-model="user" placeholder="Your GitHub username" :disabled="generated.pending" @keyup.enter="(!user)||(generated.pending)||(unusable.length > 0)||(!requests.remaining) ? null : generate()">
|
||||
<button @click="generate" :disabled="(!user)||(generated.pending)||(unusable.length > 0)||(!requests.remaining)">
|
||||
<template v-if="generated.pending">
|
||||
Generating metrics<span class="loading"></span>
|
||||
</template>
|
||||
@@ -58,7 +58,11 @@
|
||||
Generate your metrics!
|
||||
</template>
|
||||
</button>
|
||||
<small>{{ requests.remaining }} GitHub requests remaining</small>
|
||||
<small :class="{'error-text':!requests.remaining}">{{ requests.remaining }} GitHub requests remaining</small>
|
||||
<small class="warning" v-if="preview">
|
||||
Metrics are rendered by <a href="https://metrics.lecoq.io/">metrics.lecoq.io</a> in preview mode.
|
||||
Any backend editions won't be reflected but client-side rendering can still be tested.
|
||||
</small>
|
||||
<div class="warning" v-if="unusable.length">
|
||||
Metrics cannot be generated because the following plugins are not available on this web instance: {{ unusable.join(", ") }}
|
||||
</div>
|
||||
|
||||
@@ -271,6 +271,10 @@
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: var(--color-alert-error-text);
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
.warning {
|
||||
padding: .5rem .75rem;
|
||||
|
||||
15
vercel.json
Normal file
15
vercel.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"rewrites":[
|
||||
{"source": "/.templates", "destination": "/.templates__"},
|
||||
{"source": "/.templates/:template", "destination": "/.templates_/:template"},
|
||||
{"source": "/:login([-\\w]+)", "destination": "https://metrics.lecoq.io/:login"},
|
||||
{"source": "/:login([-\\w]+)/:repository([-\\w]+)", "destination": "https://metrics.lecoq.io/:login/:repository"},
|
||||
{"source": "/about/query/:login", "destination": "https://metrics.lecoq.io/about/query/:login"},
|
||||
{"source": "/.uncache", "destination": "https://metrics.lecoq.io/.uncache"},
|
||||
{"source": "/.requests", "destination": "https://metrics.lecoq.io/.requests"}
|
||||
],
|
||||
"github":{
|
||||
"silent": true,
|
||||
"autoJobCancelation": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user