Skip to content

Commit

Permalink
Merge pull request #66 from accurat/live-tunneler
Browse files Browse the repository at this point in the history
Live tunneler
  • Loading branch information
marcofugaro authored Dec 9, 2019
2 parents 1d14317 + 4daf4a8 commit e12ea26
Show file tree
Hide file tree
Showing 8 changed files with 375 additions and 13 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Then you just `cd project-name`, run `yarn start` and start creating awesome stu
#### Commands
These are the available commands once you created a project:
- `yarn start` starts a server locally, accessible both from your browser and from another machine using your same wi-fi
- `yarn start --exposed` starts a server locally and exposes it to the internet, accessible from everyone having the link, kinda like ngrok, but works only if you have an accurat ssh key. The link created looks like `{branch}.{repo}.internal.accurat.io` if you're in a branch, or `{repo}.internal.accurat.io` if you're on master. It uses a server with an instance of [SSH-Tuna](https://github.com/accurat/ssh-tuna) to achieve this.
- `yarn build` builds the project for production, ready to be deployed from the `build/` folder
- `yarn lint` lints with eslint the `src/` folder. You can pass any [eslint options](https://eslint.org/docs/user-guide/command-line-interface#options) to the lint command, for example if you want to use eslint's fix option, you do it like this:
```json
Expand Down Expand Up @@ -242,6 +243,8 @@ render() {

- **WATCH_NODE_MODULES** - Set this to true if you want to recompile when any of the used `node_modules` changes (default `false`)

- **TUNNEL_DOMAIN** - The domain that the command `yarn start --exposed` will use as a request tunnel, it must be the domain of a server with an instance of [SSH-Tuna](https://github.com/accurat/ssh-tuna) on it (default `internal.accurat.io`)

## Available Env Variables
These are the Env Variables that Accurapp provides you, you cannot modify them directly:
- **NODE_ENV** - It is equal to `'development'` in the `yarn start` command and `'production'` in the `yarn build` command
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"test": "./test/e2e.sh",
"create-test-app": "./test/create-test-app.sh",
"create-test-app-build": "(yarn create-test-app && cd test-app/ && yarn build)",
"create-test-app-start": "(yarn create-test-app && cd test-app/ && BROWSER=false yarn start)",
"create-test-app-start": "(yarn create-test-app && cd test-app/ && BROWSER=false yarn start --exposed)",
"publish": "is-git-status-clean && lerna publish --conventional-commits --message 'chore: 🚀 Publish'"
},
"husky": {
Expand Down
1 change: 1 addition & 0 deletions packages/accurapp-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"react-dev-utils": "9.0.1",
"resolve": "1.11.0",
"semver": "6.1.1",
"ssh-tuna": "^1.0.3",
"webpack": "4.34.0",
"webpack-dev-server": "3.2.1"
}
Expand Down
29 changes: 25 additions & 4 deletions packages/accurapp-scripts/scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const detect = require('detect-port')
const WebpackDevServer = require('webpack-dev-server')
const openOrRefreshBrowser = require('react-dev-utils/openBrowser')
const { prepareUrls } = require('react-dev-utils/WebpackDevServerUtils')
const { tunnelPort } = require('ssh-tuna')
const { log, coloredBanner } = require('../utils/logging-utils')
const { generateSubdomain } = require('../utils/tunnel-utils')
const { createWebpackCompiler, readWebpackConfig } = require('../utils/webpack-utils')
const { verifyTypeScriptSetup } = require('../utils/verifyTypeScriptSetup')
const {
Expand All @@ -27,6 +29,9 @@ process.env.LATEST_TAG = extractLatestTag()
const HOST = process.env.HOST || '0.0.0.0'
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 8000
const PROTOCOL = process.env.HTTPS === 'true' ? 'https' : 'http'
const TUNNEL_DOMAIN = process.env.TUNNEL_DOMAIN || 'internal.accurat.io'
const TUNNEL_SSH_PORT = process.env.TUNNEL_SSH_PORT || 2222
const EXPOSED = process.argv.includes('--exposed')

const appDir = process.cwd()
verifyTypeScriptSetup(appDir)
Expand All @@ -36,6 +41,24 @@ function runDevServer(port) {
const compiler = createWebpackCompiler(() => {
log.info(`The app is running at: ${chalk.cyan(urls.localUrlForTerminal)}`)
log.info(`Or on your network at: ${chalk.cyan(urls.lanUrlForTerminal)}`)

if (EXPOSED) {
const subdomain = generateSubdomain()
tunnelPort(port, subdomain, TUNNEL_DOMAIN, TUNNEL_SSH_PORT)
.then(() => {
const url = `https://${subdomain}.${TUNNEL_DOMAIN}`
log.info(`Even from far away at: ${chalk.cyan(url)}`)
})
.catch(err => {
const message = err.message || err
if (message.includes('authentication methods failed')) {
err =
'Could not authenticate to the tunneling server, please make sure you can access the server via ssh.'
}

log.err(`Could not expose the local port: ${err}`)
})
}
})

const devServerConfig = {
Expand Down Expand Up @@ -63,14 +86,12 @@ console.log(coloredBanner('/||||/| accurapp'))

detect(DEFAULT_PORT)
.then(port => {
if (port === DEFAULT_PORT) {
runDevServer(port)
} else {
if (port !== DEFAULT_PORT) {
log.ok(
`Something is already running on port ${DEFAULT_PORT}, switching to ${chalk.blue(port)}...`
)
runDevServer(port)
}
runDevServer(port)
return port
})
.catch(err => {
Expand Down
28 changes: 28 additions & 0 deletions packages/accurapp-scripts/utils/git-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,37 @@ function extractLatestTag() {
}
}

function extractCurrentBranch() {
try {
return cp
.execSync('git rev-parse --abbrev-ref HEAD')
.toString()
.trim()
} catch (e) {
// Probably git is not available, return an empty string instead
return ''
}
}

function extractRepoName() {
try {
return cp
.execSync('basename -s .git `git config --get remote.origin.url`', {
stdio: ['pipe', 'pipe', 'ignore'],
})
.toString()
.trim()
} catch (e) {
// Probably git is not available, return an empty string instead
return ''
}
}

module.exports = {
extractBrowserslistString,
extractLatestCommitHash,
extractLatestCommitTimestamp,
extractLatestTag,
extractCurrentBranch,
extractRepoName,
}
12 changes: 12 additions & 0 deletions packages/accurapp-scripts/utils/tunnel-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const os = require('os')
const { extractRepoName, extractCurrentBranch } = require('../utils/git-utils')

function generateSubdomain() {
const repo = extractRepoName()
const branch = extractCurrentBranch()
if (!repo) return os.hostname()
if (branch === 'master') return repo
return `${branch}.${repo}`
}

module.exports = { generateSubdomain }
6 changes: 6 additions & 0 deletions test/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ PID=$!
sleep 20s
kill $PID

# Test the start exposing to the internet
BROWSER=false yarn start --exposed &
PID=$!
sleep 20s
kill $PID

# Test the build command
yarn build

Expand Down
Loading

0 comments on commit e12ea26

Please sign in to comment.