Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live tunneler #66

Merged
merged 15 commits into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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