Retire try.html and create new dev + prod builds (#1194)
- Followup from #1163 - Retire try.html - Separate build config for dev and production - Move config for badge examples into the JS build - Move the prod transform into npm scripts - In the future this could be handled using a bundler plugin - make website builds production build as before - Run the production build in CI to make sure it’s working - Build the frontend on Heroku
This commit is contained in:
@@ -17,6 +17,7 @@ before_script:
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run test:js
|
||||
- npm run build:production
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
@@ -13,15 +13,16 @@ endif
|
||||
favicon:
|
||||
node gh-badge.js '' '' '#bada55' .png > favicon.png
|
||||
|
||||
website:
|
||||
@mkdir -p build && \
|
||||
node_modules/.bin/babel-node frontend/render-badge-examples && \
|
||||
cat frontend/fragments/try-header.html build/badge-examples-fragment.html frontend/fragments/try-footer.html > try.html && \
|
||||
cat try.html | $(SED) "s,(<img src=\")(/[^\"\?]+)\",\1https://img.shields.io\2?maxAge=2592000\"," \
|
||||
footer-production-transform:
|
||||
@$(SED) "s,(<img src=\")(/[^\"\?]+)\",\1https://img.shields.io\2?maxAge=2592000\"," \
|
||||
frontend/fragments/try-footer.html \
|
||||
| $(SED) "s,(<img src=\")(/[^\"\?]+\?[^\"]+)\",\1https://img.shields.io\2\&maxAge=2592000\"," \
|
||||
| $(SED) "s,<span id='imgUrlPrefix'>,&https://img.shields.io," \
|
||||
| $(SED) "s,var origin = '';,var origin = 'https://img.shields.io';," \
|
||||
| $(SED) "s,<style>,<!-- WARNING: THIS FILE WAS GENERATED FROM try.html -->\\"$(NEWLINE)"<style>," > index.html
|
||||
> build/try-footer.html
|
||||
|
||||
website:
|
||||
npm run build:production
|
||||
|
||||
deploy: deploy-s0 deploy-s1 deploy-s2 deploy-gh-pages
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ continuous integration services, package registries, distributions, app
|
||||
stores, social networks, code coverage services, and code analysis services.
|
||||
Every month it serves over 470 million images.
|
||||
|
||||
In addition to hosting the shields.io home page and server code, this monorepo
|
||||
In addition to hosting the shields.io frontend and server code, this monorepo
|
||||
hosts an [NPM library for generating badges][gh-badges], and the badge design
|
||||
specification.
|
||||
|
||||
@@ -118,8 +118,9 @@ Development
|
||||
1. Install Node 6 or later. You can use the [package manager][] of your choice.
|
||||
2. Clone this repository.
|
||||
3. Run `npm install` to install the dependencies.
|
||||
4. Run `node server 1111 localhost` to start the server.
|
||||
5. Open `http://localhost:1111/try.html` to view the home page.
|
||||
4. Run `npm run build` to build the frontend.
|
||||
5. Run `npm start` to start the server.
|
||||
6. Open `http://[::]:8080/` to view the home page.
|
||||
|
||||
[package manager]: https://nodejs.org/en/download/package-manager/
|
||||
|
||||
|
||||
@@ -10,7 +10,16 @@
|
||||
"website": "https://shields.io/",
|
||||
"repository": "https://github.com/badges/shields",
|
||||
"logo": "http://shields.io/favicon.png",
|
||||
"success_url": "/try.html",
|
||||
"env": {
|
||||
"INFOSITE": {
|
||||
"description": "The home page.",
|
||||
"value": "/"
|
||||
},
|
||||
"NPM_CONFIG_PRODUCTION": {
|
||||
"description": "Configure whether devDependencies are installed (they are needed for the build).",
|
||||
"value": "false"
|
||||
}
|
||||
},
|
||||
"formation": {
|
||||
"web": {
|
||||
"quantity": 1,
|
||||
|
||||
+23
-17
@@ -27,17 +27,19 @@ I suppose you have [git](https://git-scm.com/) installed.
|
||||
If you do not, install it and learn about the [Github workflow](http://try.github.io/).
|
||||
|
||||
1. [Fork][fork] this repository.
|
||||
2. Clone the fork
|
||||
2. Clone the fork
|
||||
`git clone git@github.com:YOURGITHUBUSERNAME/shields.git`
|
||||
3. `cd shields`
|
||||
4. Install npm and other required packages (Ubuntu 16.10)
|
||||
4. Install npm and other required packages (Ubuntu 16.10)
|
||||
`sudo apt-get install npm nodejs-legacy curl imagemagick`
|
||||
5. Install all packages
|
||||
5. Install all packages
|
||||
`npm install`
|
||||
6. Run the server
|
||||
6. Build the frontend
|
||||
`npm run build`
|
||||
6. Run the server
|
||||
`npm start`
|
||||
7. Visit the website to check the badges get loaded slowly:
|
||||
[http://[::1]:8080/try.html](http://[::1]/try.html)
|
||||
7. Visit the website to check the badges get loaded slowly:
|
||||
[http://[::1]:8080/](http://[::1]/)
|
||||
|
||||
(3) Open an Issue
|
||||
-----------------
|
||||
@@ -203,17 +205,21 @@ This has something to do with [private/secret.json](https://github.com/badges/sh
|
||||
|
||||
Once you are done implementing your badge, you can add it to the collection on [shields.io](http://shields.io/).
|
||||
|
||||
First, we make it visible on [http://[::1]:8080/try.html][try].
|
||||
Edit [try.html][tryhtml] in the right section (Build, Downloads, ...) and add your badge:
|
||||
First, we make it visible locally at [http://[::1]:8080/][home]. Edit
|
||||
[lib/all-badge-examples.js][allbadges] in the right category (Build,
|
||||
Downloads, ...) and add your badge:
|
||||
|
||||
```
|
||||
<tr><th data-keywords='test badge keywords for google'>Test Badge from the tutorial</th>
|
||||
<td><img src='/test/subject/STATUS.svg' alt=''/></td>
|
||||
<td><code>https://img.shields.io/test/subject/STATUS.svg</code></td>
|
||||
</tr>
|
||||
```js
|
||||
{
|
||||
title: 'Test Badge from the tutorial',
|
||||
keywords: [
|
||||
'some-search-keyword'
|
||||
],
|
||||
previewUri: '/test/subject/STATUS.svg',
|
||||
},
|
||||
```
|
||||
|
||||
Save, restart and you can see it [locally][try].
|
||||
Save, run `npm run build`, and you can see it [locally][home].
|
||||
|
||||
## (4.4) Write Tests
|
||||
|
||||
@@ -235,7 +241,7 @@ Please follow it to include tests on your pull-request.
|
||||
|
||||
## (5) Create a Pull Request
|
||||
|
||||
You have implemented changes in `server.js` and `try.html`.
|
||||
You have implemented changes in `server.js` and `lib/all-badge-examples.js`.
|
||||
These changes shall go live on shields.io.
|
||||
To do that, [create a pull-request](https://help.github.com/articles/creating-a-pull-request/).
|
||||
By doing this, your changes are made public to the shields team.
|
||||
@@ -257,9 +263,9 @@ These files can also be of help for creating your own badge.
|
||||
[example-issue]: https://github.com/badges/shields/issues/886
|
||||
[fork]: https://github.com/badges/shields/fork
|
||||
[format]: INSTALL.md#format
|
||||
[try]: http://[::1]:8080/try.html
|
||||
[home]: http://[::1]:8080/
|
||||
[server]: ../server.js
|
||||
[tryhtml]: ../try.html
|
||||
[allbadges]: ../lib/all-badge-examples.js
|
||||
[edit]: https://github.com/badges/shields/edit/master/doc/TUTORIAL.md
|
||||
[add-pr]: https://github.com/badges/shields/issues?utf8=%E2%9C%93&q=is%3Aissue%20in%3Atitle%20add%20
|
||||
[new-badge]: https://github.com/badges/shields/pulls?q=is%3Apr+label%3Anew-badge
|
||||
|
||||
+6
-8
@@ -22,13 +22,11 @@ npm install # You may need sudo for this.
|
||||
[package manager]: https://nodejs.org/en/download/package-manager/
|
||||
|
||||
|
||||
Build the index
|
||||
---------------
|
||||
|
||||
Build the "real" index page:
|
||||
Build the frontend
|
||||
------------------
|
||||
|
||||
```sh
|
||||
make website
|
||||
BASE_URL=https://your-server.example.com npm run build:production
|
||||
```
|
||||
|
||||
|
||||
@@ -50,7 +48,7 @@ node server 8080
|
||||
|
||||
The root gets redirected to https://shields.io.
|
||||
|
||||
For testing purposes, you can go to `http://localhost/try.html`.
|
||||
For testing purposes, you can go to `http://localhost/`.
|
||||
|
||||
|
||||
Heroku
|
||||
@@ -93,11 +91,11 @@ $ docker run --rm -p 8080:80 --env-file shields.env --name shields shields
|
||||
> gh-badges@1.1.2 start /usr/src/app
|
||||
> node server.js
|
||||
|
||||
http://[::1]:80/try.html
|
||||
http://[::1]/
|
||||
```
|
||||
|
||||
Assuming Docker is running locally, you should be able to get to the
|
||||
application at http://localhost:8080/try.html.
|
||||
application at http://localhost:8080/.
|
||||
|
||||
If you run Docker in a virtual machine (such as boot2docker or Docker Machine)
|
||||
then you will need to replace `localhost` with the IP address of that virtual
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const url = require('url');
|
||||
// const URL = url.URL; // Requires Node 7+.
|
||||
const { URL } = require('whatwg-url');
|
||||
const React = require('react');
|
||||
|
||||
function resolvePreviewUri (uri, baseUri, isProductionBuild) {
|
||||
if (isProductionBuild) {
|
||||
const parsed = new URL(uri, baseUri);
|
||||
parsed.searchParams.set('maxAge', 2592000);
|
||||
return parsed.toString();
|
||||
} else {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
const Badge = (props) => {
|
||||
const attrs = {};
|
||||
if (props.documentation) {
|
||||
@@ -11,9 +24,9 @@ const Badge = (props) => {
|
||||
attrs['data-keywords'] = props.keywords.join(' ');
|
||||
}
|
||||
const previewImage = props.previewUri
|
||||
? (<img src={props.previewUri} alt="" />)
|
||||
? (<img src={resolvePreviewUri(props.previewUri, props.baseUri, props.isProductionBuild)} alt="" />)
|
||||
: '\u00a0'; // non-breaking space
|
||||
const exampleUri = `https://img.shields.io${props.exampleUri || props.previewUri}`;
|
||||
const exampleUri = url.resolve(props.baseUri, props.exampleUri || props.previewUri);
|
||||
|
||||
return (
|
||||
<tr><th {... attrs}>{ props.title }:</th>
|
||||
@@ -28,7 +41,7 @@ const Category = (props) => (
|
||||
<h3 id={props.category.id}>{ props.category.name }</h3>
|
||||
<table className='badge'><tbody>
|
||||
{
|
||||
props.examples.map((badgeData, i) => (<Badge key={i} {...badgeData} />))
|
||||
props.examples.map((badgeData, i) => (<Badge key={i} {...badgeData} baseUri={props.baseUri} isProductionBuild={props.isProductionBuild} />))
|
||||
}
|
||||
</tbody></table>
|
||||
</div>
|
||||
@@ -37,7 +50,7 @@ const Category = (props) => (
|
||||
const BadgeExamples = (props) => (
|
||||
<div>
|
||||
{
|
||||
props.examples.map((categoryData, i) => (<Category key={i} {...categoryData} />))
|
||||
props.examples.map((categoryData, i) => (<Category key={i} {...categoryData} baseUri={props.baseUri} isProductionBuild={props.isProductionBuild} />))
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm ../lib/all-badge-examples.js
|
||||
cat >../lib/all-badge-examples.js <<HERE
|
||||
'use strict';
|
||||
|
||||
const allBadgeExamples =
|
||||
HERE
|
||||
|
||||
cat ../all-badges.json >> ../lib/all-badge-examples.js
|
||||
sed -Ei '' -e 's/\"([a-zA-Z]+)\":/\1:/' ../lib/all-badge-examples.js
|
||||
sed -Ei '' -e "s/\"/\'/g" ../lib/all-badge-examples.js
|
||||
|
||||
cat >>../lib/all-badge-examples.js <<HERE
|
||||
|
||||
module.exports = allBadgeExamples;
|
||||
HERE
|
||||
@@ -1,50 +0,0 @@
|
||||
// Generate a JSON file from try.html with the initial badge example data.
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const inputPath = path.join(__dirname, '..', 'try.html');
|
||||
const html = fs.readFileSync(inputPath);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const sectionHeaders = $('h3');
|
||||
|
||||
const sections = [];
|
||||
|
||||
$('table.badge').each((i, table) => {
|
||||
const category = {
|
||||
id: sectionHeaders.eq(i).attr('id'),
|
||||
name: sectionHeaders.eq(i).text().trim(),
|
||||
};
|
||||
|
||||
const examples = [];
|
||||
|
||||
$(table).find('tr').each((i, row) => {
|
||||
const th = $(row).find('th');
|
||||
const keywordsAttr = th.attr('data-keywords');
|
||||
|
||||
const previewUri = $(row).find('img').attr('src');
|
||||
const exampleUri = $(row).find('code').text().replace(/^https:\/\/img\.shields\.io/, '');
|
||||
|
||||
const rowData = {
|
||||
title: th.text().trim().replace(/:$/, ''),
|
||||
previewUri,
|
||||
keywords: keywordsAttr ? keywordsAttr.split(' ') : undefined,
|
||||
documentation: th.attr('data-doc'),
|
||||
};
|
||||
|
||||
if (exampleUri !== previewUri) {
|
||||
rowData.exampleUri = exampleUri;
|
||||
}
|
||||
|
||||
examples.push(rowData);
|
||||
})
|
||||
|
||||
sections.push({ category, examples });
|
||||
})
|
||||
|
||||
const outputPath = path.join(__dirname, '..', 'all-badges.json');
|
||||
fs.writeFileSync(outputPath, JSON.stringify(sections, 0, 2));
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const envFlag = require('node-env-flag');
|
||||
const React = require('react');
|
||||
const ReactDOMServer = require('react-dom/server');
|
||||
const pretty = require('pretty');
|
||||
@@ -11,8 +12,11 @@ const BadgeExamples = require('./badge-examples');
|
||||
// const badgeExampleData = JSON.parse(fs.readFileSync(inputPath));
|
||||
const badgeExampleData = require('../lib/all-badge-examples');
|
||||
|
||||
const baseUri = process.env.BASE_URL || 'https://img.shields.io';
|
||||
const isProductionBuild = envFlag(process.env.PRODUCTION_BUILD, false);
|
||||
|
||||
const fragment = ReactDOMServer.renderToStaticMarkup(
|
||||
<BadgeExamples examples={badgeExampleData} />);
|
||||
<BadgeExamples examples={badgeExampleData} {...{baseUri, isProductionBuild}} />);
|
||||
|
||||
const outputPath = path.join(__dirname, '..', 'build', 'badge-examples-fragment.html');
|
||||
fs.writeFileSync(outputPath, pretty(fragment));
|
||||
|
||||
Generated
+65
@@ -4568,6 +4568,12 @@
|
||||
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
|
||||
"dev": true
|
||||
},
|
||||
"lolex": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.3.tgz",
|
||||
@@ -4927,6 +4933,31 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-env-flag": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-env-flag/-/node-env-flag-0.1.0.tgz",
|
||||
"integrity": "sha1-vn1DxRHCeBqg+GiOfY9Cb3WSS8U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chai": "4.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"chai": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
|
||||
"integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assertion-error": "1.0.2",
|
||||
"check-error": "1.0.2",
|
||||
"deep-eql": "3.0.1",
|
||||
"get-func-name": "2.0.0",
|
||||
"pathval": "1.1.0",
|
||||
"type-detect": "4.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
||||
@@ -8204,6 +8235,40 @@
|
||||
"integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=",
|
||||
"dev": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.3.0.tgz",
|
||||
"integrity": "sha512-rM+hE5iYKGPAOu05mIdJR47pYSR2vDzfrTEFRc/S8D3L60yW8BuXmUJ7Kog7x/DrokFN7JNaHKadpzjouKRRAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.sortby": "4.7.0",
|
||||
"tr46": "1.0.1",
|
||||
"webidl-conversions": "4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
|
||||
"integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
|
||||
"dev": true
|
||||
},
|
||||
"tr46": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
|
||||
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "2.1.0"
|
||||
}
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"whatwg-url-compat": {
|
||||
"version": "0.6.5",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
|
||||
|
||||
+12
-3
@@ -52,8 +52,14 @@
|
||||
"test:services:pr:run": "mocha --delay service-tests/runner/cli.js --stdin < pull-request-services.log",
|
||||
"test:services:pr": "npm run test:services:pr:prepare && npm run test:services:pr:run",
|
||||
"test": "npm run lint && npm run test:js",
|
||||
"build": "make website",
|
||||
"start": "node server 8080 ::"
|
||||
"prebuild:examples": "mkdirp build",
|
||||
"build:examples": "node_modules/.bin/babel-node frontend/render-badge-examples",
|
||||
"build:copy-fragments": "cp frontend/fragments/try-header.html frontend/fragments/try-footer.html build/",
|
||||
"build:concat": "cat build/try-header.html build/badge-examples-fragment.html build/try-footer.html > index.html",
|
||||
"build": "npm run build:examples && npm run build:copy-fragments && npm run build:concat",
|
||||
"build:production": "PRODUCTION_BUILD=true npm run build:examples && npm run build:copy-fragments && make footer-production-transform && npm run build:concat",
|
||||
"heroku-postbuild": "npm run build",
|
||||
"start": "INFOSITE=/ node server 8080 ::"
|
||||
},
|
||||
"bin": {
|
||||
"badge": "./gh-badge.js"
|
||||
@@ -93,8 +99,10 @@
|
||||
"is-svg": "^2.1.0",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^4.0.1",
|
||||
"nock": "^9.0.13",
|
||||
"node-env-flag": "^0.1.0",
|
||||
"node-fetch": "^1.6.3",
|
||||
"nyc": "^11.2.1",
|
||||
"opn-cli": "^3.1.0",
|
||||
@@ -105,7 +113,8 @@
|
||||
"read-all-stdin-sync": "^1.0.5",
|
||||
"rimraf": "^2.6.2",
|
||||
"semver-regex": "^1.0.0",
|
||||
"sinon": "^4.0.1"
|
||||
"sinon": "^4.0.1",
|
||||
"whatwg-url": "^6.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6",
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../try.html
|
||||
@@ -19,7 +19,7 @@ var tryUrl = require('url').format({
|
||||
protocol: secureServer ? 'https' : 'http',
|
||||
hostname: bindAddress,
|
||||
port: serverPort,
|
||||
pathname: 'try.html',
|
||||
pathname: '/',
|
||||
});
|
||||
var log = require('./lib/log.js');
|
||||
var badge = require('./lib/badge.js');
|
||||
@@ -7261,9 +7261,11 @@ function(data, match, end, ask) {
|
||||
}
|
||||
});
|
||||
|
||||
// Redirect the root to the website.
|
||||
camp.route(/^\/$/, function(data, match, end, ask) {
|
||||
ask.res.statusCode = 302;
|
||||
ask.res.setHeader('Location', infoSite);
|
||||
ask.res.end();
|
||||
});
|
||||
if (infoSite !== '/') {
|
||||
// Redirect the root to the website.
|
||||
camp.route(/^\/$/, function(data, match, end, ask) {
|
||||
ask.res.statusCode = 302;
|
||||
ask.res.setHeader('Location', infoSite);
|
||||
ask.res.end();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ runner.
|
||||
Here's the output:
|
||||
|
||||
```
|
||||
http://localhost:1111/try.html
|
||||
http://localhost:1111/
|
||||
Travis CI
|
||||
build status on default branch
|
||||
✓
|
||||
@@ -197,7 +197,7 @@ t.create('build status on named branch')
|
||||
```
|
||||
|
||||
```
|
||||
http://localhost:1111/try.html
|
||||
http://localhost:1111/
|
||||
Travis CI
|
||||
build status on default branch
|
||||
✓
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
# Base URL for redirects etc.
|
||||
BASE_URL=http://localhost:8080
|
||||
# Where your homepage is
|
||||
INFOSITE=http://localhost:8080/try.html
|
||||
INFOSITE=http://localhost:8080/
|
||||
|
||||
# GitHub settings
|
||||
GITHUB_URL=https://api.github.com
|
||||
|
||||
Reference in New Issue
Block a user