Skip to content

Commit

Permalink
Create npm package of built CSS, JS, and macros (#143)
Browse files Browse the repository at this point in the history
* Added copy functionality for components and page templates

* Change output destination for images and css

* Copy assets for npm bundle

* Add npmignore

* svgo optimisation added

* Update gitignore

* Tell travis to run the npm-bundle task if a there is a tag

* Rename package

* Set version to match tag

* Have travis increment package.json to tag value and deploy to npm

* Remove unnecessary step

* Try get travis to deploy tags

* Try get travis to deploy

* Add email address

* New npm API key

* Attempt to get travis to at least set the tag

* Fix sortable table background sprite

* Please tag the relase travis

* Travis please

* Travis please version my package.json

* 0.0.9

* Try to get travis to set version in master

* Tell git to checkout origin master

* Put build task back in to stop travis from running the tests

* Run fetch before checkout

* Trying to get travis to checkout master

* Check what branch we're on

* 0.0.14

* See if updates branch

* See if removing HEAD works

* Try get travis to checkout master

* Remove unused function

* run git fetch

* show-ref

* Show ref

* Put build back in

* Try new checkout mechanism

* Add git status

* Set package.json version

* Change to use travis branch

* Add git push

* Try push to origin master

* Try push to origin master

* Add more logging

* See if i can check out master

* More loggin

* Checkout local master

* Set script to null

* Put build back

* Remove unnecessary code

* Moment of truth

* Set package to publish publically

* Add description

* Add test stage back in

* Ensure tests are run first

* Remove --allow-same-version

* Try get travis to deploy built bundle

* Update npm version commands

* Change package version

* Set travis to run bundle scriot before deploy

* Set travis to run bundle scriot before deploy

* Add git status to see if that stops error

* Fix npmignore and set travis.yml back to working version

* Fix travis.yml

* Added section about npm dependency to readme

* Correct yarn command

* Dont run tests for releases

* Added documentation about changing credentials for npm and github
  • Loading branch information
bameyrick committed Feb 8, 2019
1 parent db6b49c commit 28d8e49
Show file tree
Hide file tree
Showing 15 changed files with 1,503 additions and 39 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ build/
.DS_store
coverage/
.vscode/
# npm package folders
/components/
/page-templates/
/css/
/favicons/
/fonts/
/img/
/scripts/
10 changes: 10 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*
!/components/**/*
!/css/**/*
!/favicons/**/*
!/fonts/**/*
!/img/**/*
!/page-templates/**/*
!/scripts/**/*
!/LICENSE
!/package.json
25 changes: 24 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
language: node_js
node_js:
- "10.14.2"
- 10.14.2
cache: yarn
jobs:
include:
- stage: test
script: yarn test
- stage: npm-bundle
script: yarn npm-bundle && npm version $TRAVIS_BRANCH --allow-same-version -m "chore - release version %s [skip ci]" --allow-empty
deploy:
- provider: npm
skip_cleanup: true
email: bameyrick@gmail.com
api_key:
secure: wOxnxRRtCSxAS88DpUGBjx4ktYo4UQVIAiAozo/AfbyaENuboQJ1THB1CZDRSHzERt7A62/2IB3mRjFj/PyghtYH1CiLojzE5qHSorGimjIzR2eBW2KSWUfBHe8beE5flo3yzh7HQ39yGO4cjY0jvr2dIaYHyU6QkdYPWpG1EN/TkPr4ZEaXAS8zWAzoi3+b4Ya+iHcr1wArblbykYzVuh2tmnJRNHWUdJmZg30965hb/jg8VdpeHQHRHttYdATfq/f09z6BLBOrwcyidE2o8R7s0QOVagnsisTb+EnsUTduueokRQZY1Een70+F0DJPubQ84/eVTxdBmA0vEess1NboBhHKG9Kd3Xbzg3+OlvE84XRrDBvI6AXwgSj40VsYmtNFTJqJCz/ad1LMW5BK6PNTVCIf9CbthZuYwRX9hNwWjoiauGzyh9Z8sfIxXU3pgdIDNtfk+hEjp2p4BqDwcrZ9myjKKDw90y8pxd9ZELEY5nxiIAbfLT1wNVoByNiqHykLOxQurYT7Zj1KefC4UPqRvcIv8VuaGDHpEqz0UW7EfOC7n0QH7vCLMxztXcyrOpxrDCvBGwk2sgK6+vImkPyb1iC29EuOTux1URtot4BK0YgyDl71PpjEVJIYgBXHCh2tW/LGtC7cuw7vMh+PhnIAP8U0Pw65LYteh+WrlDM=
on:
tags: true
- provider: script
script: bash .travis/pu.sh
on:
tags: true
stages:
- name: test
if: tag IS NOT present
- name: npm-bundle
if: tag IS present
39 changes: 39 additions & 0 deletions .travis/pu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh

setup_git() {
# Set the user name and email to match the API token holder
# This will make sure the git commits will have the correct photo
# and the user gets the credit for a checkin
git config --global user.email "bameyrick@gmail.com"
git config --global user.name "Ben Meyrick"
git config --global push.default matching

# Get the credentials from a file
git config credential.helper "store --file=.git/credentials"

# This associates the API Key with the account
echo "https://${GITHUB_API_KEY}:@github.com" > .git/credentials
}

make_version() {
local build_head=$(git rev-parse HEAD)

git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
git fetch
git fetch --tags

# create the tacking branches
for branch in $(git branch -r|grep -v HEAD) ; do
git checkout -qf ${branch#origin/}
done

git checkout master

# %s is the placeholder for the created tag
npm version $TRAVIS_BRANCH -m --allow-same-version "chore - release version %s [skip ci]" --allow-empty

git push origin master
}

setup_git
make_version
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
[![Github last commit](https://img.shields.io/github/last-commit/ONSdigital/pattern-library-v2.svg)](https://github.com/ONSdigital/pattern-library-v2/commits)
[![Github contributors](https://img.shields.io/github/contributors/ONSdigital/pattern-library-v2.svg)](https://github.com/ONSdigital/pattern-library-v2/graphs/contributors)

## Installing as a dependency

Nunjucks macros for components and templates are available from npm. Built CSS and JS is also available if you need access to pre-release CSS/JS, otherwise CSS and JS should be loaded from the CDN.

```bash
yarn add @ons/design-system
```

## Run Locally

You'll need [Git](https://help.github.com/articles/set-up-git/), [Node.js](https://nodejs.org/en/), and [Yarn](https://yarnpkg.com/en/docs/getting-started) to run this project locally.
Expand Down
16 changes: 16 additions & 0 deletions docs/automatic-npm-releasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Automatic npm releasing

When you create a release (and a tag is created) a Travis build will kick off and start building a npm bundle which will be deployed to npm. The task will also update the version value in the `package.json` on master automatically.

Currently the deploy to npm and git commits are deployed/pushed using API keys for Ben Meyrick's (`bameyrick@gmail.com`) GitHub account. If these need changing there are some prerequisites:

### npm account

- You must be a collaborator on the @ons/design-system package
- You may have 2FA enabled but only for authentication
- The API token **must** be encrypted using the Travis CLI

### GitHub account

- You must be an administrator of the repository
- The branch protection rules for `master` should be set to **not** apply to administrators, or Travis won't be able to update the package.json version with the latest tag
139 changes: 139 additions & 0 deletions lib/generate-npm-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as fs from 'fs';

import rimraf from 'rimraf';

const cwd = process.cwd();
const sourcePath = `${cwd}/src`;
const componentsPath = `${sourcePath}/components`;
const newComponentsPath = `${cwd}/components`;
const templatesPath = `${sourcePath}/styles/page-template/src`;
const newTemplatesPath = `${cwd}/page-templates`;
const assetFolders = ['css', 'favicons', 'fonts', 'img', 'scripts'];
const builtAssetsFolders = assetFolders.map(folder => `${cwd}/build/${folder}`);

async function removeExistingFolders() {
const folders = [newComponentsPath, newTemplatesPath, ...assetFolders];

await asyncForEach(folders, removeFolder);
}

async function removeFolder(folderPath) {
try {
if (await fs.existsSync(folderPath)) {
await rimraf.sync(folderPath);
}
} catch (error) {
throw new Error(error);
}
}

async function copyComponents() {
await createFolder(newComponentsPath);

try {
const items = await fs.readdirSync(componentsPath).filter(path => !path.includes('.njk'));

items.forEach(await copyComponent);
} catch (error) {
throw new Error(error);
}
}

async function copyComponent(componentName) {
try {
const componentPath = `${componentsPath}/${componentName}/src`;
const newComponentPath = `${newComponentsPath}/${componentName}`;

const items = await fs.readdirSync(componentPath).filter(path => path.includes('.njk'));

if (items.length) {
await createFolder(newComponentPath);
}

items.forEach(async path => {
await copyFile(`${componentPath}/${path}`, `${newComponentPath}/${path}`);
});
} catch (error) {
throw new Error(error);
}
}

async function copyTemplates() {
await createFolder(newTemplatesPath);

try {
const items = await fs.readdirSync(templatesPath).filter(path => path.includes('.njk'));

items.forEach(await copyTemplate);
} catch (error) {
throw new Error(error);
}
}

async function copyTemplate(templateFileName) {
try {
await copyFile(`${templatesPath}/${templateFileName}`, `${newTemplatesPath}/${templateFileName}`);
} catch (error) {
throw new Error(error);
}
}

async function copyAssets() {
await asyncForEach(assetFolders, async (folder, index) => {
await createFolder(folder);

try {
const builtPath = builtAssetsFolders[index];
const files = await fs.readdirSync(builtPath).filter(path => !path.includes('patternlib'));

asyncForEach(files, async file => {
if (file.match(/(\.\w+)$/)) {
await copyFile(`${builtPath}/${file}`, `${folder}/${file}`);
} else {
const newFolderPath = `${folder}/${file}`;
const nestedBuiltPath = `${builtPath}/${file}`;
await createFolder(newFolderPath);

const nestedFiles = await fs.readdirSync(nestedBuiltPath).filter(path => !path.includes('patternlib'));

asyncForEach(nestedFiles, async nestedFile => {
await copyFile(`${nestedBuiltPath}/${nestedFile}`, `${newFolderPath}/${nestedFile}`);
});
}
});
} catch (error) {
throw new Error(error);
}
});
}

async function createFolder(folderPath) {
try {
await fs.mkdirSync(folderPath);
} catch (error) {
throw new Error(error);
}
}

async function copyFile(filePath, newComponentPath) {
try {
await fs.copyFileSync(filePath, newComponentPath);
} catch (error) {
throw new Error(error);
}
}

async function asyncForEach(array, callback) {
for (let index = 0, arrayLength = array.length; index < arrayLength; index++) {
await callback(array[index], index, array);
}
}

async function run() {
await removeExistingFolders();
await copyComponents();
await copyTemplates();
await copyAssets();
}

run();
19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "ons-design-system",
"name": "@ons/design-system",
"description": "ONS Design System built CSS, JS, and Nunjucks templates",
"version": "0.0.0-alpha",
"main": "index.js",
"license": "MIT",
Expand All @@ -8,15 +9,20 @@
"name": "Ben Meyrick",
"url": "https://github.com/bameyrick"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"start": "rm -rf build && yarn webpack-dev-server --host 0.0.0.0 --watch --config webpack.dev.babel.js",
"build": "rm -rf build && yarn webpack --config webpack.prod.babel.js",
"start": "yarn tidy-clean && yarn webpack-dev-server --host 0.0.0.0 --watch --config webpack.dev.babel.js",
"build": "yarn tidy-clean && yarn webpack --config webpack.prod.babel.js",
"check-unused": "npx npm-check-unused",
"lint-staged": "lint-staged",
"test": "karma start ./src/tests/config/karma.conf.js && karma start ./src/tests/config/karma.conf.nomodule.js && codecov",
"test:browserstack": "TEST_ON_BROWSERSTACK=true karma start ./src/tests/config/karma.conf.js && TEST_ON_BROWSERSTACK=true karma start ./src/tests/config/karma.conf.nomodule.js",
"test:local": "KARMA_SINGLE_RUN=false karma start ./src/tests/config/karma.conf.js",
"dedupe-deps": "npx yarn-deduplicate yarn.lock"
"dedupe-deps": "npx yarn-deduplicate yarn.lock",
"tidy-clean": "rm -rf build css favicons fonts img components page-templates scripts coverage",
"npm-bundle": "NODE_ENV=production yarn build && babel-node lib/generate-npm-package.js"
},
"browserslist": [
"last 2 versions",
Expand All @@ -26,7 +32,7 @@
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"post-checkout": "yarn check"
"post-checkout": "yarn tidy-clean && yarn check"
}
},
"lint-staged": {
Expand All @@ -48,6 +54,7 @@
},
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/node": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.1.6",
Expand All @@ -73,6 +80,7 @@
"glob": "^7.1.3",
"highlight.js": "^9.13.1",
"husky": "^1.2.0",
"imagemin-webpack-plugin": "^2.4.1",
"iframe-resizer": "^3.6.5",
"istanbul-instrumenter-loader": "^3.0.1",
"karma": "^3.1.3",
Expand Down Expand Up @@ -108,6 +116,7 @@
"remark-lint": "^6.0.4",
"remark-preset-lint-recommended": "^3.0.2",
"rewiremock": "^3.13.0",
"rimraf": "^2.6.3",
"sass-lint": "^1.12.1",
"sass-loader": "^7.1.0",
"url-loader": "^1.1.2",
Expand Down
2 changes: 1 addition & 1 deletion src/components/button/src/_button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
bottom: 0;
left: 0;
margin: auto;
background-image: url('../img/loader.svg');
background-image: url('#{$static}/img/loader.svg');
background-repeat: no-repeat;
background-position: center center;
background-size: 1.5rem;
Expand Down
2 changes: 1 addition & 1 deletion src/components/table/src/_table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
width: 12px;
height: 21px;
background-size: 100%;
background-image: url('../img/icons/icons--sort-sprite.svg');
background-image: url('#{$static}img/icons/icons--sort-sprite.svg');
background-repeat: no-repeat;
background-position: 0 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/scss/vars/_vars.scss
Original file line number Diff line number Diff line change
@@ -1 +1 @@
$static: '../';
$static: '/';
4 changes: 2 additions & 2 deletions src/views/layouts/_master.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="/favicons/favicon.ico">
<title>{{ pageInfo.title }}</title>
<link rel="stylesheet" href="/responsive.css">
<link rel="stylesheet" href="/patternlib.css">
<link rel="stylesheet" href="/css/responsive.css">
<link rel="stylesheet" href="/css/patternlib.css">
</head>

<body class="patternlib-page{{ ' patternlib-page--example' if example }}">
Expand Down
Loading

0 comments on commit 28d8e49

Please sign in to comment.