Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Publish scripts for deployment to npm via travis. (#14)
  • Loading branch information
excitement-engineer committed Jan 29, 2017
1 parent ecd6eb1 commit 80d4ceb
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 20 deletions.
9 changes: 1 addition & 8 deletions .gitignore
Expand Up @@ -2,13 +2,6 @@

dist/

# Generated when running 'npm pack'
graphql-iso-date-1.0.1.tgz

# Generated when running 'yarn pack'
graphql-iso-date-v1.0.1.tgz


### Node ###
# Logs
logs
Expand Down Expand Up @@ -50,4 +43,4 @@ jspm_packages

### WebStorm ###

.idea/
.idea/
31 changes: 24 additions & 7 deletions .travis.yml
@@ -1,11 +1,28 @@
language: node_js

cache: yarn

node_js:
- "7"
- "6"
- "5"
- "4"
- '7'
- '6'
- '5'
- '4'

script:
- if [[ "$TRAVIS_JOB_NUMBER" == *.1 ]]; then npm test; else npm run testonly; fi

after_failure:
- (cd resources; python travis_after_all.py)

after_success:
- (cd resources; python travis_after_all.py)
- export $(cat resources/.to_export_back)

script: yarn run travis
deploy:
provider: npm
skip_cleanup: true
email: "dirkjanrutten@gmail.com"
api_key:
secure: VezZd77ytFyIGsRB124Z9fDDppm/MiHARrHRv8ZvEH1sdj39Y/Gm54381FuUSbaoemnWlOnRtgspaKjdyJsBwKUkhTJaud6YZqP2NIG4xSBJHRxnqOJ7PbLSFusXKq429wJE8DZTb/d/M9lPG/DxrinTDtp+7r/YAnkljGMOjDLhxwR544iHh9lzWUN/s9RHOs6klaE0oKzh36AFdcukSWOe5E9v8CJBJlhid9UJzmnjb9NTv0tjX9VP9dON6kkDO5XvNzwKmdu62Y4ch4WtyDXMSqxy01a46XduW5qVOVdlza3PxTq2Y2Zu0ok3rRzKKlxA35qGvWFbtskbZcdRkWOa5aIxaAFK+F1bKhuKRHidufzZLtiP9fVAC0sF+AOpMjQBhBBScvZU5S35yQUU+elesg9w+3+IELp7v0C/bOQYkUWEhgdmyCTxxwtITvvLSOAe/L0zumBz5v6j7spquDJ7x/ZkqmMxBvIzxmgnJXUdgaSJCTBoB3MhsIJiHXfAwdJ6ficOgAkaKSoDSqIf7N9cZWWl2iBJ9fow+6mzmKvfNROc+yFu6e1843XrwTSPFAD2Xx3Js2BGwhZz6h+3NoRaASgb3+bKAj04DN33OMxnCMHsXqQyKBx8dUSWBxQMafD0KeroVZ6fC4rQqMndRj8vFWuJO1+43Ja7Gn8V9CQ=
on:
tags: true
branch: master
condition: "$BUILD_LEADER$BUILD_AGGREGATE_STATUS = YESothers_succeeded"
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
@@ -0,0 +1,18 @@
## Release on NPM

*Only core contributors may release to NPM.*

To release a new version on NPM, first ensure all tests pass with `npm test`,
then use `npm version patch|minor|major` in order to increment the version in
package.json and tag and commit a release. Then `git push && git push --tags`
this change so Travis CI can deploy to NPM. *Do not run `npm publish` directly.*
Once published, add [release notes](https://github.com/excitement-engineer/graphql-iso-date/tags).
Use [semver](http://semver.org/) to determine which version part to increment.

Example for a patch release:

```sh
npm test
npm version patch
git push --follow-tags
```
10 changes: 5 additions & 5 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "graphql-iso-date",
"version": "3.0.0",
"version": "2.1.0",
"description": "A set of RFC 3339 compliant date/time GraphQL scalar types.",
"main": "dist/index.js",
"homepage": "https://github.com/excitement-engineer/graphql-iso-date",
Expand All @@ -14,12 +14,12 @@
"scripts": {
"examples": "npm run build && babel-node examples/index.js",
"build": "babel src --ignore __tests__,*.test.js --out-dir dist/",
"test": "jest",
"test": "npm run examples && npm run testonly && npm run check && npm run lint",
"testonly": "jest",
"watch": "jest --watch",
"check": "flow check",
"prepublish": "npm run build",
"lint": "standard",
"travis": "npm run test && npm run check && npm run lint && npm run examples"
"prepublish": ". ./resources/prepublish.sh",
"lint": "standard"
},
"keywords": [
"GraphQL",
Expand Down
32 changes: 32 additions & 0 deletions resources/prepublish.sh
@@ -0,0 +1,32 @@
# This script is adapted from https://github.com/graphql/graphql-js.

# Because of a long-running npm issue (https://github.com/npm/npm/issues/3059)
# prepublish runs after `npm install` and `npm pack`.
# In order to only run prepublish before `npm publish`, we have to check argv.
if node -e "process.exit(($npm_config_argv).original[0].indexOf('pu') === 0)"; then
exit 0;
fi

# Publishing to NPM is currently supported by Travis CI, which ensures that all
# tests pass first and the deployed module contains the correct file structure.
# In order to prevent inadvertently circumventing this, we ensure that a CI
# environment exists before continuing.
if [ "$CI" != true ]; then
echo "\n\n\n \033[101;30m Only Travis CI can publish to NPM. \033[0m" 1>&2;
echo " Ensure git is left is a good state by backing out any commits and deleting any tags." 1>&2;
echo " Then read CONTRIBUTING.md to learn how to publish to NPM.\n\n\n" 1>&2;
exit 1;
fi;

# When Travis CI publishes to NPM, we need to make
# sure that the files are built into dist.
npm run build;

# Ensure a vanilla package.json before deploying so other tools do not interpret
# The built output as requiring any further transformation.
node -e "var package = require('./package.json'); \
delete package.scripts; \
delete package.options; \
delete package.devDependencies; \
delete package.standard; \
require('fs').writeFileSync('package.json', JSON.stringify(package));"
101 changes: 101 additions & 0 deletions resources/travis_after_all.py
@@ -0,0 +1,101 @@
"""
https://github.com/dmakhno/travis_after_all/blob/master/travis_after_all.py
"""

import os
import json
import time
import logging

try:
import urllib.request as urllib2
except ImportError:
import urllib2

log = logging.getLogger("travis.leader")
log.addHandler(logging.StreamHandler())
log.setLevel(logging.INFO)

TRAVIS_JOB_NUMBER = 'TRAVIS_JOB_NUMBER'
TRAVIS_BUILD_ID = 'TRAVIS_BUILD_ID'
POLLING_INTERVAL = 'LEADER_POLLING_INTERVAL'

build_id = os.getenv(TRAVIS_BUILD_ID)
polling_interval = int(os.getenv(POLLING_INTERVAL, '5'))

#assume, first job is the leader
is_leader = lambda job_number: job_number.endswith('.1')

if not os.getenv(TRAVIS_JOB_NUMBER):
# seems even for builds with only one job, this won't get here
log.fatal("Don't use defining leader for build without matrix")
exit(1)
elif is_leader(os.getenv(TRAVIS_JOB_NUMBER)):
log.info("This is a leader")
else:
#since python is subprocess, env variables are exported back via file
with open(".to_export_back", "w") as export_var:
export_var.write("BUILD_MINION=YES")
log.info("This is a minion")
exit(0)


class MatrixElement(object):
def __init__(self, json_raw):
self.is_finished = json_raw['finished_at'] is not None
self.is_succeeded = json_raw['result'] == 0
self.number = json_raw['number']
self.is_leader = is_leader(self.number)


def matrix_snapshot():
"""
:return: Matrix List
"""
response = urllib2.build_opener().open("https://api.travis-ci.org/builds/{0}".format(build_id)).read()
raw_json = json.loads(response)
matrix_without_leader = [MatrixElement(element) for element in raw_json["matrix"]]
return matrix_without_leader


def wait_others_to_finish():
def others_finished():
"""
Dumps others to finish
Leader cannot finish, it is working now
:return: tuple(True or False, List of not finished jobs)
"""
snapshot = matrix_snapshot()
finished = [el.is_finished for el in snapshot if not el.is_leader]
return reduce(lambda a, b: a and b, finished), [el.number for el in snapshot if
not el.is_leader and not el.is_finished]

while True:
finished, waiting_list = others_finished()
if finished: break
log.info("Leader waits for minions {0}...".format(waiting_list)) # just in case do not get "silence timeout"
time.sleep(polling_interval)


try:
wait_others_to_finish()

final_snapshot = matrix_snapshot()
log.info("Final Results: {0}".format([(e.number, e.is_succeeded) for e in final_snapshot]))

BUILD_AGGREGATE_STATUS = 'BUILD_AGGREGATE_STATUS'
others_snapshot = [el for el in final_snapshot if not el.is_leader]
if reduce(lambda a, b: a and b, [e.is_succeeded for e in others_snapshot]):
os.environ[BUILD_AGGREGATE_STATUS] = "others_succeeded"
elif reduce(lambda a, b: a and b, [not e.is_succeeded for e in others_snapshot]):
log.error("Others Failed")
os.environ[BUILD_AGGREGATE_STATUS] = "others_failed"
else:
log.warn("Others Unknown")
os.environ[BUILD_AGGREGATE_STATUS] = "unknown"
#since python is subprocess, env variables are exported back via file
with open(".to_export_back", "w") as export_var:
export_var.write("BUILD_LEADER=YES {0}={1}".format(BUILD_AGGREGATE_STATUS, os.environ[BUILD_AGGREGATE_STATUS]))

except Exception as e:
log.fatal(e)

0 comments on commit 80d4ceb

Please sign in to comment.