Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from nhsuk/feature/hello-world
Browse files Browse the repository at this point in the history
hello world
  • Loading branch information
st3v3nhunt authored Feb 21, 2018
2 parents 0660e35 + 58ed136 commit ec857f7
Show file tree
Hide file tree
Showing 39 changed files with 5,665 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git/
node_modules/
Dockerfile
README.md
npm-debug.log
npm-debug.log.*
.DS_Store
*.swp
.idea/*
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage/
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "nhsuk"
}
31 changes: 31 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!--
Thanks for wanting to contribute to this repository.
In order for the changes to be integrated into the repo with as little friction
as possible please follow the guidance here. This includes completing all
sections as fully as possible.
Prior to creating a Pull Request, please ensure there is an open issue for the
changes you wish to make. This will provide visibility to others early in the
process. Potentially other people will wish to help out. It also allows us to
validate the change is inline with our vision for the product.
Provide a general summary of your changes in the Title
-->

## Description
<!--- Describe your changes in detail -->

## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## Checklist
<!-- Ensure each of the points below have been considered and completed where applicable -->
- [ ] An [ADR](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
- [ ] New and/or updated tests
- [ ] Changes log in `CHANGELOG`
6 changes: 6 additions & 0 deletions .istanbul.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
check:
global:
statements: 80
lines: 80
branches: 37
functions: 80
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
language: node_js
node_js: node
services: docker

before_install: yarn global add greenkeeper-lockfile@1

before_script: greenkeeper-lockfile-update

script: bash ./scripts/test-ci

after_script:
- docker-compose -f docker-compose-tests.yml down -v
- greenkeeper-lockfile-upload

after_success: bash ./scripts/deploy.sh
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Eva Barabas (https://github.com/beseven)
Mark Harrop (https://github.com/markysoft)
Steven Hunt (https://github.com/st3v3nhunt)
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0.1.0 / / TBA
=======
- Initial application architecture
71 changes: 71 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Contribution Guidelines

We welcome patches to NHS.UK products, as long as you follow these guidelines:

## Git workflow

- Pull requests must contain a succinct, clear summary of what the user need is driving this feature change
- Follow our [Git styleguide](https://github.com/nhsuk/styleguides/blob/master/git.md)
- Make a feature branch, ideally in the format `feature/summary-of-change` e.g. `feature/add-login`
- Ensure your branch contains logical atomic commits before sending a pull request - follow our [Git styleguide](https://github.com/nhsuk/styleguides/blob/master/git.md)
- Pull requests are automatically tested, where applicable using [Travis CI](https://travis-ci.org/), which will report back on whether the tests still pass on your branch
- You *may* rebase your branch after feedback if it's to include relevant updates from the master branch. We prefer a rebase here to a merge commit as we prefer a clean and straight history on master with discrete merge commits for features
- Using a single emoji to start the commit message is encouraged. See the other commits in the repo for examples

## Copy

- URLs should use hyphens, not underscores

## Code

- Must be readable with meaningful naming, e.g. no shorthand single character variable names
- Follow our [styleguides](https://github.com/nhsuk/styleguides)
- Must pass linting with the ruleset from `.eslint.json` (`yarn run lint`). Lint will run on all commits, rebases and as part of CI

## Testing

Write tests.

## Versioning

We use [Semantic Versioning](http://semver.org/), and bump the version
on master only. Please don't submit your own proposed version numbers.

## Browser support

Your code should be tested in the browsers listed below.

The lists are based on usage statistics for NHS Choices (current NHS.UK) and
represent approximately 95% of the most popular browsers.

Each browser is assigned a ‘level of support’ that your service should meet.
‘Compliant’ means your service must look as good as it does in other modern
browsers.

If a browser is assigned a ‘functional’ level of support, it means your service
might not look perfect but must still be usable.

‘Latest version’ refers to the latest stable version and the version immediately
before that.

### Desktop

| Operating system | Browser | Support |
| ---------------- | ------- | ------- |
| Windows | Internet Explorer 8+ | Compliant |
| | Edge (latest version) | Compliant |
| | Google Chrome (latest version) | Compliant |
| | Mozilla Firefox (latest version) | Compliant |
| Mac OS X | Safari 8+ | Compliant |
| | Google Chrome (latest version) | Compliant |
| | Mozilla Firefox (latest version) | Compliant |

### Small screen devices

| Operating system | Version | Browser | Support |
| ---------------- | ------- | ------- | ------- |
| iOS | 7+ | Mobile Safari | Compliant |
| | | Google Chrome | Compliant |
| Android | 4.x | Google Chrome | Compliant |
| | | Android Browser | Compliant |
| Windows Phone | 8.1 | Internet Explorer | Compliant |
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM node:8.9.1-alpine

# RUN apk add --no-cache python=2.7.13-r1 git-perl bash make gcc g++
# RUN rm /bin/sh && ln -s /bin/bash /bin/sh
ENV USERNAME nodeuser

RUN adduser -D $USERNAME && \
mkdir /code && \
chown $USERNAME:$USERNAME /code

USER $USERNAME
WORKDIR /code

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
COPY yarn.lock package.json /code/

RUN if [ "$NODE_ENV" == "production" ]; then yarn install --production --pure-lockfile; else yarn install --pure-lockfile; fi

EXPOSE 3000

COPY . /code

USER root
RUN find /code -user 0 -print0 | xargs -0 chown $USERNAME:$USERNAME
USER $USERNAME

# RUN APP DIRECTLY TO AVOID SPAWNING SUBPROCESSES IN DOCKER
CMD [ "node", "app.js" ]
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# sexual-health-service-finder
Helping to connect people to sexual health services.
# Sexual Health Service Finder
> Helping to connect people to sexual health services.
[![GitHub Release](https://img.shields.io/github/release/nhsuk/sexual-health-service-finder.svg)](https://github.com/nhsuk/sexual-health-service-finder/releases/latest/)
[![Greenkeeper badge](https://badges.greenkeeper.io/nhsuk/sexual-health-service-finder.svg)](https://greenkeeper.io/)
[![Build Status](https://travis-ci.org/nhsuk/sexual-health-service-finder.svg?branch=master)](https://travis-ci.org/nhsuk/sexual-health-service-finder)
[![Coverage Status](https://coveralls.io/repos/github/nhsuk/sexual-health-service-finder/badge.svg?branch=master)](https://coveralls.io/github/nhsuk/sexual-health-service-finder?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/github/nhsuk/sexual-health-service-finder/badge.svg)](https://snyk.io/test/github/nhsuk/sexual-health-service-finder)
8 changes: 8 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const log = require('./app/lib/logger');
const app = require('./server');
const applicationStarts = require('./app/lib/promCounters').applicationStarts;

app.listen(app.port, () => {
applicationStarts.inc(1);
log.info(`Express server listening on port ${app.port}`);
});
4 changes: 4 additions & 0 deletions app/lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
ASSETS_URL: 'https://assets.nhs.uk',
SITE_ROOT: '/find-a-chlamydia-test',
};
1 change: 1 addition & 0 deletions app/lib/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('nhsuk-bunyan-logger')('sexual-health-service-finder');
9 changes: 9 additions & 0 deletions app/lib/promBundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const expressPromBundle = require('express-prom-bundle');
const buckets = require('./constants').promHistogramBuckets;

const promBundle = expressPromBundle({ includePath: true, buckets });

module.exports = {
middleware: promBundle,
promClient: promBundle.promClient,
};
6 changes: 6 additions & 0 deletions app/lib/promCounters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const promClient = require('./promBundle').promClient;

module.exports = {
applicationStarts: new promClient.Counter({ name: 'app_starts', help: 'The number of times the application has been started' }),
errorPageViews: new promClient.Counter({ name: 'error_page_views', help: 'The number of error page views' }),
};
7 changes: 7 additions & 0 deletions app/middleware/locals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// eslint-disable-next-line no-unused-vars
module.exports = config =>
(req, res, next) => {
res.locals.SITE_ROOT = req.app.locals.SITE_ROOT;
res.locals.ASSETS_URL = req.app.locals.ASSETS_URL;
next();
};
1 change: 1 addition & 0 deletions app/views/error-404.nunjucks
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
404 placeholder!
1 change: 1 addition & 0 deletions app/views/error.nunjucks
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error placeholder!
12 changes: 12 additions & 0 deletions config/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('path');

const rootPath = path.normalize(`${__dirname}/..`);

module.exports = {
app: {
name: 'sexual-health-service-finder',
},
env: process.env.NODE_ENV || 'development',
root: rootPath,
port: process.env.PORT || 3000,
};
119 changes: 119 additions & 0 deletions config/express.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const bodyParser = require('body-parser');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const express = require('express');
const helmet = require('helmet');
const nunjucks = require('nunjucks');
const constants = require('../app/lib/constants');
const errorCounter = require('../app/lib/promCounters').errorPageViews;
const locals = require('../app/middleware/locals');
const log = require('../app/lib/logger');
const promBundle = require('../app/lib/promBundle').middleware;
const router = require('./routes');

module.exports = (app, config) => {
// eslint-disable-next-line no-param-reassign
app.locals.SITE_ROOT = constants.SITE_ROOT;
// eslint-disable-next-line no-param-reassign
app.locals.ASSETS_URL = constants.ASSETS_URL;
// start collecting default metrics
promBundle.promClient.collectDefaultMetrics();

app.set('views', `${config.root}/app/views`);
app.set('view engine', 'nunjucks');
const nunjucksEnvironment =
nunjucks.configure(`${config.root}/app/views`, {
autoescape: true,
express: app,
watch: true,
});
log.debug({ config: { nunjucksEnvironment } }, 'nunjucks environment configuration');

app.use(helmet({
frameguard: { action: 'deny' },
hsts: { includeSubDomains: false },
contentSecurityPolicy: {
directives: {
defaultSrc: [
'\'self\'',
],
childSrc: [
'*.hotjar.com',
],
scriptSrc: [
'\'self\'',
'data:',
'*.google-analytics.com',
'*.hotjar.com',
'*.webtrends.com',
'*.webtrendslive.com',
],
imgSrc: [
'\'self\'',
'data:',
'*.google-analytics.com',
'*.hotjar.com',
'*.webtrends.com',
'*.webtrendslive.com',
'*.nhs.uk',
],
styleSrc: [
'\'self\'',
'*.nhs.uk',
],
fontSrc: [
'*.nhs.uk',
],
connectSrc: [
'\'self\'',
'*.hotjar.com:*',
],
},
}
}));

app.use(locals(config));

app.use((req, res, next) => {
log.debug({ req });
next();
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));

app.use(cookieParser());
app.use(compression());

app.use(constants.SITE_ROOT, express.static(`${config.root}/public`));

// metrics needs to be registered before routes wishing to have metrics generated
// see https://github.com/jochen-schweizer/express-prom-bundle#sample-uusage
app.use(promBundle);
app.use(constants.SITE_ROOT, router);
app.use(constants.SITE_ROOT, (req, res) => {
log.warn({ req }, 404);
res.status(404);
res.render('error-404');
});

// eslint-disable-next-line no-unused-vars
app.use(constants.SITE_ROOT, (err, req, res, next) => {
const statusCode = err.statusCode || 500;

errorCounter.inc(1);
log.error({ error: { err, req, res } }, 'Error');
res.status(statusCode);
res.render('error', {
message: err,
error: app.get('env') === 'development' ? err : {},
title: 'error',
});
});

app.get('/', (req, res) => {
res.redirect(constants.SITE_ROOT);
});
};
5 changes: 5 additions & 0 deletions config/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const router = require('express').Router();

router.get('/', (req, res) => res.send('Hello World!'));

module.exports = router;
Loading

0 comments on commit ec857f7

Please sign in to comment.