Skip to content

Commit

Permalink
merged in main
Browse files Browse the repository at this point in the history
  • Loading branch information
biw committed Mar 17, 2021
1 parent 9328894 commit 35b7424
Show file tree
Hide file tree
Showing 43 changed files with 3,738 additions and 971 deletions.
31 changes: 31 additions & 0 deletions .cfignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

.env

docs/_book/
65 changes: 65 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
version: 2.1

commands:
install_and_cache_yarn_linux:
steps:
- checkout
- restore_cache:
name: restore cache ➡ root
keys:
- dependencies-linux-root-{{ checksum "yarn.lock" }}
# fallback to using the latest cache if no exact match is found
- dependencies-linux-root-
- run:
name: yarn ➡ install
command: yarn
- save_cache:
name: save cache
paths:
- ~/repo/node_modules
key: dependencies-linux-root-{{ checksum "yarn.lock" }}
run_all_tests:
steps:
- run:
name: yarn test
command: yarn test
install_and_test:
steps:
- install_and_cache_yarn_linux
- run_all_tests

# based on https://github.com/nodejs/Release schedule
jobs:
node_10:
docker:
- image: circleci/node:10
steps:
- install_and_test
node_12:
docker:
- image: circleci/node:12
steps:
- install_and_test
node_13:
docker:
- image: circleci/node:13
steps:
- install_and_test
node_14:
docker:
- image: circleci/node:14
steps:
- install_and_test
node_15:
docker:
- image: circleci/node:15
steps:
- install_and_test
workflows:
main:
jobs:
- node_10
- node_12
- node_13
- node_14
- node_15
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules/
docs/
test/
schema.png
CHANGES.md
LICENSE
README.md
Procfile
.eslintrc
.git/
.gitignore
.npmignore
.travis.yml
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space

# 4 space indentation
[*.{js,ts,tsx,jsx,json}]
indent_size = 2

# Tab indentation (no size specified)
[*.yml]
indent_size = 4
18 changes: 18 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"rules": {
"indent": [ 2, 4 ],
"quotes": [ 2, "single" ],
"linebreak-style": [ 2, "unix" ],
"semi": [ 2, "always" ],
"no-unused-vars": [ 2, {
"vars": "all",
"args": "none"
} ],
"spaced-comment": [ 2, "always" ]
},
"env": {
"node": true,
"mocha": true
},
"extends": "eslint:recommended"
}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ build/Release
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

.env
.env

docs/_book/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
5 changes: 0 additions & 5 deletions .travis.yml

This file was deleted.

5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

### 3.0.0
- Rewrite to be cleaner
- Support for other backends than GitHub
- Better disk caching

### 2.6.0
- Add `/notes` endpoint to get changelog
- GitHub authentication is now optional for public repos (Thanks @ide)
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM mhart/alpine-node:5.8.0

# Switch to /app
WORKDIR /app
# Install deps
COPY package.json ./
RUN npm install --production
# Copy source
COPY . ./

# Ports
ENV PORT 80
EXPOSE 80

ENTRYPOINT ["npm", "start"]
1 change: 0 additions & 1 deletion Procfile

This file was deleted.

179 changes: 6 additions & 173 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Nuts is a simple (and smart) application to serve desktop-application releases.

![Schema](./schema.png)
![Schema](./docs/schema.png)

It uses GitHub as a backend to store assets, and it can easily be deployed to Heroku as a stateless service. It supports GitHub private repositories (useful to store releases of a closed-source application available on GitHub).

Expand All @@ -29,184 +29,17 @@ It uses GitHub as a backend to store assets, and it can easily be deployed to He
- :sparkles: Release notes endpoint
- `/notes/:version`
- :sparkles: Up-to-date releases (GitHub webhooks)
- :sparkles: Atom/RSS feeds for versions/channels

#### Deploy it / Start it

Install dependencies using:
[Follow our guide to deploy Nuts](https://nuts.gitbook.com/deploy.html).

```
$ npm install
```

This service requires to be configured using environment variables:

```
# Set the port for the service
$ export PORT=6000
# Access token for the GitHub API (requires permissions to access the repository)
# If the repository is public you do not need to provide an access token
# you can also use GITHUB_USERNAME and GITHUB_PASSWORD
$ export GITHUB_TOKEN=...
# ID for the GitHub repository
$ export GITHUB_REPO=Username/MyApp
# Authentication for the private API
$ export API_USERNAME=hello
$ export API_PASSWORD=world
```

Then start the application using:

```
$ npm start
```

#### Assets for releases

Nuts uses some filename/extension conventions to serve the correct asset to a specific request:

Platform will be detected from the filename:

- Windows: filename should contain `win`
- Mac/OS X: filename should contain `mac` or `osx`
- Linux: filename should contain `linux`

By default releases are tagged as 32-bits (except for OSX), but 64-bits will also be detected from filenames.

Filetype and usage will be detected from the extension:

- `.dmg` will be served in priority to Mac users
- `.nupkg` will only be served to Squirrel.Windows requests
- Otherwise, `.zip` are advised (Linux, Mac, Windows and Squirrel.Mac)

#### Download urls

Nuts provides urls to access releases assets. These assets are cached on the disk.

* Latest version for detected platform: `http://download.myapp.com/download/latest` or `http://download.myapp.com/download`
* Latest version for specific platform: `http://download.myapp.com/download/latest/osx` or ``http://download.myapp.com/download/osx`
* Specific version for detected platform: `http://download.myapp.com/download/1.1.0`
* Specific version for specific platform: `http://download.myapp.com/download/1.2.0/osx`
* Specific channel: `http://download.myapp.com/download/channel/beta`
* Specific channel for specific platform: `http://download.myapp.com/download/channel/beta/osx`

#### Platforms

Platforms can be detected from user-agent and are normalized to values: `osx`, `osx_32`, `osx_64`, `linux`, `linux_32`, `linux_64`, `windows`, `windows_32`, `windows_64`.

Non-prefixed platform will be resolve to 32 bits (except for OSX).

#### Auto-updater / Squirrel

This server provides an endpoint for [Squirrel auto-updater](https://github.com/atom/electron/blob/master/docs/api/auto-updater.md): `http://download.myapp.com/update/osx/:currentVersion`.

###### Squirrel.Mac

This url requires different parameters to return a correct version: `version` and `platform`.

For example with Electron's `auto-updater` module:

```js
var app = require('app');
var os = require('os');
var autoUpdater = require('auto-updater');

var platform = os.platform() + '_' + os.arch();
var version = app.getVersion();

autoUpdater.setFeedUrl('http://download.myapp.com/update/'+platform+'/'+version);
```

###### Squirrel.Windows

Nuts will serve NuGet packages on `http://download.myapp.com/update/win32/:version/RELEASES`.

Your application just need to configurer `Update.exe` or `Squirrel.Windows` to use `http://download.myapp.com/update/win32/:version` as a feed url (:warning: without query parameters).

You'll just need to upload as release assets: `RELEASES`, `*-delta.nupkg` and `-full.nupkg` (files generated by `Squirrel.Windows` releaser).

#### ChangeLog

Nuts provides a `/notes` endpoint that output release notes as text or json.

#### Private API

A private API is available to access more infos about releases and stats. This API can be protected by HTTP basic auth (username/password) using configuration `API_USERNAME` and `API_PASSWORD`.

List versions:

```
GET http://download.myapp.com/api/versions
```

Get details about specific version:

```
GET http://download.myapp.com/api/version/1.1.0
```

Resolve a version:

```
GET http://download.myapp.com/api/resolve?platform=osx&channel=alpha
```

List channels:

```
GET http://download.myapp.com/api/channels
```

Get stats about downloads:

```
GET http://download.myapp.com/api/stats
```

#### GitHub Webhook

Add `http://download.myapp.com/refresh` as a GitHub webhook to refresh versions cache everytime you update a release on GitHub.

The secret can be configured using `GITHUB_SECRET` (default value is `secret`).

#### Integrate it as a middleware

Nuts can be integrated into a Node.JS application as a middleware. Using the middleware, you can add custom authentication on downloads or analytics for downloads counts.

```js
var express = require('express');
var Nuts = require('nuts-serve');

var app = express();
var nuts = Nuts(
// GitHub configuration
repository: "Me/MyRepo",
token: "my_api_token",

// Timeout for releases cache (seconds)
timeout: 60*60,

// Folder to cache assets (by default: a temporary folder)
cache: './assets',

// Pre-fetch list of releases at startup
preFetch: true,

// Secret for refresh webhook
refreshSecret: 'my-secret',
This server provides an endpoint for [Squirrel auto-updater](https://github.com/atom/electron/blob/master/docs/api/auto-updater.md), it supports both [OS X](https://nuts.gitbook.com/update-osx.html) and [Windows](https://nuts.gitbook.com/update-windows.html).

// Middlewares
onDownload: function(version, req, res, next) {
console.log('download', download.version.tag, "on channel", download.version.channel, "for", download.platform.type);
next();
},
onAPIAccess: function(req, res, next) {
next();
}
);
#### Documentation

app.use('/myapp', nuts);
app.listen(4000);
```
[Check out the documentation](https://nuts.gitbook.com) for more details.
Loading

0 comments on commit 35b7424

Please sign in to comment.