Giter VIP home page Giter VIP logo

spaship's Introduction

SPAship · Build Status codecov

SPAship is an early-stages Single-Page App deployment and hosting platform.

Getting started

To install SPAship's command-line interface: npm install @spaship/cli adding -g installs the package globally. To initialize a project: spaship init this will create a spaship.yml file based on your answers to the prompts. To deploy: create an archive by zipping the contents of a directory (let's call our file "Archive.zip" and target environment dev), then spaship deploy Archive.zip --env=dev

Packages

SPAship consists of a few packages, found inside the packages directory.

  • CLI - the spaship command-line interface
  • Router - a service for dynamically proxying requests to SPAs, or to remote systems
  • Manager - a web UI for managing SPAs
  • API - an API for deploying SPAs
  • Common - common utility functions for reading/writing config files, etc

Testing

SPAship packages can be tested in one command by running npm test at the root of the repository.

You can also test individual packages by moving into their directory and running npm test. For example:

cd packages/common
npm test

Each package may have extra testing options. Please see package READMEs for more about testing them, such as how to run a test watcher.

Contributing

Contributing is awesome! 😎 This section is very much in progress, but here are a handful of established contribution guidelines.

Commit message style

We use Conventional Commits. It's a simple, standardized way to prefix commit messages. The major benefits are that CHANGELOGs can be updated automatically, and version bumps can also be automated. Please visit conventionalcommits.org and read up on how to use it. It's painless, I promise!

Also, if you're working in a development branch, please don't worry about proper commit message format. Stick to the "commit early & often" mantra. The only requirement is that when your pull request is merged, choose "Squash & Merge" and write a proper conventional-commit message. Here's a short screencap of how to do that.

squash and merge screencap

Release process

There are two commands to create and publish a new release.

  1. GH_TOKEN="YOUR_TOKEN" npm run autorelease
  2. npm run autopublish

Note: "YOUR_TOKEN" is a placeholder; please replace it with a GitHub personal access token. When creating a personal access token, the only option that needs to be checked is "public_repo". Also, your GitHub user must have write access to this repository.

Here is more detail about what autorelease and autopublish do.

autorelease

npm run autorelease does a few things.

  • Automatically bump the version number of any packages which have changed since the last tag. The type of version bump (major, minor, patch) is chosen automatically based on the types of changes found in the conventional commit log. For instance, a BREAKING CHANGE will result in a major version bump, while feat will result in a minor bump.
  • Update each package's CHANGELOG.md files, and aggregate those updates into the monorepo's root CHANGELOG.md
  • Create a git tag for the new version
  • Create a "release" object in github

autorelease is a wrapper around lerna version.

autopublish

autopublish will publish to NPM any packages that were updated by autorelease. This command is meant to be run after autorelease.

Recovering from autorelease with bad GH_TOKEN

If something goes wrong when you run autorelease, such as an invalid or forgotten GH_TOKEN, that's okay. Versions will still be bumped, git tags will still be created and pushed. The only thing missing is the GitHub Release description. To remedy that, go to spaship/releases. You should see a release listed for the new version number, but it will be lacking a description. Click on it, then click Edit Release. Paste the relevant lines from CHANGELOG.md into the description. That's it!

spaship's People

Contributors

akhilmhdh avatar arkaprovob avatar ayushsatyam146 avatar deepsource-autofix[bot] avatar dependabot[bot] avatar djfaucette avatar ftjhai avatar gautamkrishnar avatar hybridx avatar jared-sprague avatar kotwani2883 avatar kunyan avatar mudit94 avatar mwcz avatar nikhitamore avatar pjain24 avatar renovate-bot avatar renovate[bot] avatar riginoommen avatar sayak-sarkar avatar shruticode81 avatar snyk-bot avatar soumyadip007 avatar tanyutu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spaship's Issues

[spa-manager] add tests

Add test framework and a few baseline tests in each package. More tests can be written in the future, this is just about laying the foundation.

Need audit log

Log anytime a user performs a deploy, or delete operation. This can be just to a log file at the beginning, but could be moved to a database later.

API key generation page

The user should be able to generate/revoke a apiKey
The API key has expire date as optional

MongoDB config should not use only one string

I know using following way to connect mongodb is easy for use

mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test&connectTimeoutMS=300000

But we will use the MongoDB instance with authentication. it means there should be some secret inside
In the OpenShift, we always store them into single value

example:

  • MONGODB_USER
  • MONGODB_PASSWORD
  • MONGODB_DATABASE

It is very difficult to put them together into one string with OpenShift secret mapping.
Please read each value from environments

[path-proxy] add tests

  • set up mock webroot using mockfs
  • make requests to path-proxy and verify the requests are proxied to the correct origin (local mock disk, or remote env)
  • try variations of URL paths involing underscores, similar to the tests for flatpath

test: API test

  • Add script for /deploy and /list

  • Update the script with API key

Tools: newman

sync-service and path-proxy use the same port

Both sync-service and path-proxy refer to the same environment variable for their port setting, SPASHIP_PORT. I propose removing that var and creating SPASHIP_API_PORT and SPASHIP_PROXY_PORT.

[api] refactor deploy.js

deploy.js was slapped together for the proof of concept demo and needs to be rewritten. We need to make it easier to understand and easier to test.

have router fetch flatDirectories list from api

Currently, path-proxy needs disk access to the webroot in order to build its list of SPA directory names. It then refreshes the directory list every 750ms. I'd like to consider changing this behavior slightly, by adding an endpoint to sync-service that returns the directory list. This would allow path-proxy to fetch the directory list without direct disk access, so we could run it on a different host for example.

path-proxy example

- let flatDirectories = await fsp.readdir(config.get("webroot"));
+ await fetch(`${syncServiceUrl}/spaDirs`);

Redux/Mobx integration

The manager becoming to more and more complex, the state management looks been a critical issue we will meet soon.

I have familiar with redux with react. but feels it has too many duplicate code.
Maybe mobx is good a choice.
I'll do some research for this part

rename path-proxy, sync-service, and spa-manager

Rename a few packages to make things clearer.

sync-serviceapi

  • rename npm @spaship/sync-service package to @spaship/api
  • rename repo directory: /packages/sync-service to /packages/api
  • bulk rename all sync-service references within the repo to api

spa-managermanager

  • rename npm @spaship/spa-manager package to @spaship/manager
  • rename repo directory: /packages/spa-manager to /packages/manager
  • bulk rename all spa-manager references within the repo to manager

path-proxyrouter

  • rename npm @spaship/path-proxy package to @spaship/router
  • rename repo directory: /packages/path-proxy to /packages/router
  • bulk rename all path-proxy references within the repo to router

other tasks

  • rename github labels
  • publish new packages to npm
  • npm deprecate old packages, leave a message about the new package names

Fastify vs Express

It might be worth investigating using fastify instead of express. It has a lot of advantages and also a Red Hatter is one of the maintainers.

[sync-service] don't cache 400+ autosync responses

Right now autosync will cache any HTTP response. It should be adjusted to only cache when the response is a 200.

We're using axios which followed redirects (up to 5 redirects in a row, by default), so we don't have to worry about handling 300s. The response we get from axios should be a 200 if the request was successful. If it's not, drop it and leave the existing cache in place.

Create user guide for end users

Great job with the contributor guide! But I have a nice container platform at my disposal and I want to ship some SPAs. Let's have a user's guide ... pretty please? :)

add a logging system

We should add a logging system to enforce consistency and provide logging features. Right now I'm liking winston a lot. Definitely open to other options though.

Checklist:

  • added logging to common
  • added logging to sync-service
  • added logging to path-proxy

Consider pulling Spandx into the SPAship family

@mwcz Was talking to Chris and others during the trip and there is some desire to make Spandx part of the SPAship suite of tools for frontend devs. This issue is to discuss the pros and cons of pulling in Spandx under the SPAship umbrella.

add an ownership field to spaship.yaml

Each SPA should have a configuration field for who owns it. It could be an email address for an individual or a team mailing list.

Need to decide what to name it. I'm thinking owner but I'm very open to other ideas.

Here's a mocked up example:

name: My SPA
path: /my/spa
owner: [email protected]

(re SPASHIP-109)

Include-agnostic chrome injection

Talking to Chris, he suggested that we add a feature to automatically inject chrome SSI includes based on regex, like putting header right after the tag. This would be optional and people could still use SSI directly. This would also be per-instance, so you would define regex includes for access.redhat.com instance of spaship.

Create REST endpoints for API keys

This is related to #163

Create REST endpoints for creating, fetching and deleting API keys. The functions implementing key creation and deletion already exist in sync-service/lib/db.apikey.js, they just need to be wired up to URL paths in express.

Here's my thoughts on endpoint paths and HTTP methods.

HTTP method path result
POST /apikey creates and returns an API key object such as { key: "ABCD" }
DELETE /apikey?hashedKey=e12e115a Deletes key ABCD (hashed to "e12e115a") 1 2
GET /apikey?user=babyyoda Returns an API key object such as { user: "babyyoda", key: "ABCD" }
GET /user?hashedKey=ABCD Returns an API key object such as { user: "babyyoda" }
DELETE /user?user=babyyoda Deletes all API keys for user babyyoda

Notes
1 The function deleteKey(apikey) function wants you to pass in the HASHED key, not the original key (since SPA manager does not have access to the original key when you click "Delete key"). That's why the querystring param is hashedKey and not key.
2 This should return a JSON object describing whether the key creation was successful or not (key deleted successfully, or key not found).

Create express middleware function to verify API keys

Create an express middleware function that verifies API keys, and apply that function to every express endpoint that needs auth.

Note, https://github.com/spaship/spaship/blob/master/packages/sync-service/lib/db.apikey.js already provides functions for creating, storing, and verifying API keys. This issue is asking for an express middleware function that uses db.apikey.js to enforce API key auth on certain endpoints. The function getUserByKey is the best one to use for validating that an incoming API key is valid.

It should work something like this:

  1. HTTP request comes in
  2. If no Authorization header, return 401
  3. If Authorization header exists and is of the form Authorization: APIKey MY_API_KEY then get the value of MY_API_KEY and pass it into db.apikey.getUserByKey("MY_API_KEY") to determine if it's a valid key. Proceed to step 6.
  4. If Authorization header exists and is of the form Authorization: Bearer MY_TOKEN then get the value of MY_TOKEN and validate it with a JWT validation library.
    1. If the token is valid, take the sub property (we treat this property as a UUID for users) and pass it into db.apikey.getKeysByUser(sub) and proceed to step 6.
  5. If Authorization header exists but is not of the form Authorization: APIKey MY_KEY or Authorization: Bearer MY_TOKEN, then return a 403
  6. If the function returns a non-empty array, allow the request to proceed (by passing through to the next middleware function). If it returns an empty array, return a 403.

Todo: determine which endpoints need auth.

init.html should not in root directory

Now. the init.html is not in scm.

I suggest we should put it into OpenShift configMap. then it could be mount into the Pod.
But if you want to mount it to some path, the content of path will be overwrite. that's is why I suggest init.html not put into root path of SPA directory.

I think we could put it into /_include_/init.html.
The chrome snippets could also put into /_chrome_/.
It should not be able to read by path proxy or sync-service list api

Consider TypeScript

Opening this issue to have a discussion about TypeScript and whether SPAship should be 100% TS. I recall @kunyan and @sayak-sarkar both bringing up TS in past discussions.

The question to answer here is: Should we be writing this tool in TypeScript?

For fun, I've been converting a very old side-project to TS and it's been quite nice. I mostly write vanilla JS though, so it would be a bit of a learning curve for me.

In addition to all the typical pros and cons of TypeScript, here are some additional project-specific points to consider:

  • spa-manager is already in TS
  • sync-service, common, path-proxy, and the cli are already written in vanilla JS
  • if we switch, now is the best possible time
  • the cli framework (oclif) is nicer to work with in typescript
  • some devs (me for instance) are not TS experts

What does everyone think? @Jared-Sprague @kunyan @sayak-sarkar @npatil9

[api] add tests

Unit tests:

  • lib/background/autosync.js
  • lib/deploy.js (pending #47)
  • lib/metadata.js

Funcional tests:

  • POST /deploy
  • GET /list
  • POST /autosync/forceSyncAll

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.