Giter Club home page Giter Club logo

satis-control-panel's Introduction

Scrutinizer Code Quality Build Status

Satis Control Panel

Satis Control Panel (SCP) is a simple web UI for managing your Satis Repository for Composer Packages.

SCP backend is written in Laravel and with a React + Typescript combo.

Features

  • simple UI for managing your Satis configuration file for both - private packages and public packages mirrored from Packagist
  • no database required - only PHP and optional Nodejs server for automatic generation of Satis configuration file
  • RESTful API for integration with CI services
  • SCP comes with Atlassian plugins for Bamboo and Stash to ease managing package building
  • Cron job for automatic build of public packages mirrored from Packagist

Installation

You can install SCP directly with Composer by running

composer create-project realshadow/satis-control-panel [--stability-dev]

After that you can rename example.env to .env and set required configuration options.

Building javascript

npm run build

// or

npm run build-win

During development you can start Webpack dev server with

npm start

or run Gulp watcher for less files with

gulp watch

Satis configuration file

In resources/ directory you will find satis.json.dist file which holds default Satis configuration, copy this file and rename it to satis.json and edit the name and homepage property.

cp resources/satis.json.dist resources/satis.json

When you are done, you have to set correct permissions for your configuration file for web user. E.g. www-data, should be able to read/write this file). More in next Permissions section.

Permissions

For building to work correctly you have to set correct permissions to few directories/directories:

  • bootstrap/cache/
  • storage/
  • public/private/
  • public/public/
  • resources/satis.json

Each directory/file should be readable/writable by web user, e.g. www-data. For example:

chmod -R ug+rwx bootstrap/cache storage public/private public/public
chmod ug+rwx resources/satis.json

Webserver setup

Your document root should point to the public folder in the root as per default Laravel setup

Apache - example vhost

<VirtualHost *:80>
        ServerName satis.example.com

        DocumentRoot /var/www/html/satis.example.com/public
</VirtualHost>

Nginx - example vhost

server {
        listen   80 default_server;

        root /var/www/html/satis.example.com/public;
        index index.php index.html index.htm;

        location / {
             try_files $uri $uri/ /index.php$is_args$args;
        }

        # pass the PHP scripts to FastCGI server liste_ning on /var/run/php5-fpm.sock
        location ~ \.php$ {
                try_files $uri /index.php =404;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}

Visiting your control panel and generated packages

The control panel is located at http://{host}/control-panel and the packages will be generated (after first build of course) at http://{host}/public and http://{host}/private respectively.

Separating them like this adds a bit more configuration options. If for example you want to only use private packages, you can change the directory of private_repository configuration option to public instead of public/private and have your packages generated at http://{host} and still have a functioning control panel.

Configuration options

Here is a list of configuration options that can be set in config/satis.php (some of them can be set in .env file as well for convenience):

Option Description Default value Can be set in .env
config Path to satis configuration file resources/satis.json Yes
composer_home Composer home directory (thi storage/composer Yes
composer_cache Composer cache directory storage/composer/cache Yes
memory_limit Memory limit that will be set before running Satis build command 2G No
build_verbosity Verbosity of Satis build command (more info will be stored in logs) vvv No
private_repository Directory where Satis will generate private repository. This also serves as a way to distinguish public and private repositories in repository address, e.g. satis.example.com/private private No
public_repository Directory where Satis will generate public repository. This also serves as a way to distinguish public and private repositories in repository address, e.g. satis.example.com/public public No
proxy.http Proxy address that will be used by Satis/Composer for HTTP requests null Yes
proxy.https Proxy address that will be used by Satis/Composer for HTTPS requests null Yes
proxy.https See https://www.selenic.com/mercurial/hg.1.html#environment-variables for details null Yes

Note: if you change the default directory, remember to set correct permissions for your new directory.

How it works

SCP manages a single Satis configuration file which is generated on the fly when specific UI actions are performed. During each generation cycle the file is split into public and private repository configuration file, because private packages use funcionality that doesn't work well with Packagist (it will try to mirror whole Packagist repository).

Besides adding, editing and removing packages/repositories from configuration file, UI allows you to build/rebuild every package or run a complete rebuild of all registered packages/repositories.

Build process can run synchronously or asynchronously (by redirecting output to /dev/null and spawning a new process). By default, all builds run asynchronously, except on Windows where they are forced to run synchronously. This can be also forced during during API request by setting async_mode to false.

Missing or broken mirrored configuration files

Since the configuration files mirroring is triggered by any UI action, it is not always the correct behaviour. If you want to manually trigger config generation, for example when you make changes directly on the server, you can trigger the config generation with this artisan command

php artisan satis:make:config

UI State

During build process whole UI is locked. During asynchronous builds UI state is handled by Node server, but running it is completely optional.

It can be started with

npm run server

and will run on port 9010 by default. This can be changed in node/config.json file.

If for some reason UI will stay locked even though no packages are currently being build, it can be unlocked by running:

php artisan satis:persister:unlock

Composer auth

Composer file auth.json can be put in COMPOSER_HOME directory where you can put your Github token or credentials for needed for private repositories.

Private packages

Private packages are identified by repository URL address. When you will add/edit a new repository you can choose its type. By default, all repositories are considered as VCS repository. Building and rebuilding is handled by partial update functionality introduced in this PR only repositories that have a URL can be managed in UI. Those include:

  • vcs
  • hg
  • pear
  • composer
  • artifact
  • path

Adding support for more repository types is planned in future.

Private packages use the repositories config key with require-all options set to true, thus all known packages are taken out of registered repositories, which means that Packagist must be disabled by default. This is handled when configs are split into private public part.

Public (packagist) packages

Public packages are used for mirroring of existing packages that can be installed from Packagist if you are behind a corporate proxy, thus speeding up overall development and deployment time.

All packages added here are fully mirrored with all their dependencies (but we still skip dev-dependencies). Currently only one version constraint is used and that's * so we can get a complete packagist clone.

Adding support for custom version constraints is planned in future.

Since full rebuild in this case could potentionally take few hours, you can use provided Cron task for a daily rebuild (see Cron task section).

Note though that you should not try to mirror whole Packagist repository!

RESTful API

SCP comes with built in API for esier integration with your favorite CI solution.

Private packages

Private packages use md5 encoded repository url as ID.

  • get all repositories
GET control-panel/api/repository
  • get one repository
GET control-panel/api/repository/{repository_id}
  • add new repository
POST control-panel/api/repository
{
    'url': 'foo',
    'type: 'bar'
}
  • update existing repository
PUT control-panel/api/repository/{repository_id}
{
    'url': 'foo',
    'type: 'bar'
}
  • delete existing repository
DELETE control-panel/api/repository/{repository_id}

All methods return HTTP 404 if no repository is found.

Note: same API can be used for public packages as well by replacing repository by package. Although remote control of public packages is not necessary.

Additional API options

During both POST and PUT requests two additional options can be provided:

  • async_mode - true/false => if the build should run synchronously or asynchronously (all builds run asynchronously by default)
  • disable_build - true/false => if set to true Satis build command won't be run

Logs

All logs can be found in storage/logs directory. Logs are divided into:

  • api_request.log - logs all API requests
  • builder_async.log - logs all builds that run asynchronously, keep in mind that each asynchronous build has its own log file in async subdirectory identified by its timestamp
  • builder_sync.log - logs all builds that run synchronously
  • cron.log - for cron task logs

Cron task

Since mirroring of public packages can take some time and running full rebuild from UI is not a good idea, because this will lock it during the build process, SCP comes with a built in cron task that runs daily and will rebuild all repositories. It can be triggered with a cron entry similar to this:

* * * * * php /path/to/satis-folder/artisan schedule:run >> /dev/null 2>&1

Alternatively, you can add this cron entry:

00 00 * * * curl --request POST --header "Content-Length: 0" --header "X-Requested-With: XMLHttpRequest" http://{scp-url-address}/control-panel/build-public

This can be used for private packages as well

00 00 * * * curl --request POST --header "Content-Length: 0" --header "X-Requested-With: XMLHttpRequest" http://{scp-url-address}/control-panel/build-private

Atlassian plugins

SCP was created in an environment which uses Atlassian Stash and Bamboo as part of CI and thus two plugins were needed to completely integrate Composer packages into our build process.

  • Stash Satis Build Hook - a post receive hook that will register and trigger a build/rebuild of your package in SCP (if you want to skip deployment process)
  • Bamboo Satis Build - a deployment task for rebuilding currently deployed Composer package in Satis repository

Both use partial update functionality which was introduced in this PR.

TODO

  • option to import composer.lock file for public packages
  • option to use more types of private packages
  • option to write custom version constraints for public packages
  • option to see what's going during long running builds of public packages
  • better handling of race conditions during simultaneous writes/reads
  • authentification? (this can be simply handled with htpasswd)
  • ????

PR's are welcome

Alternatives

satis-control-panel's People

Contributors

antonkomarev avatar dubrsl avatar freezy-sk avatar mattzuba avatar neilime avatar realshadow 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  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

satis-control-panel's Issues

node server.js need to support SSL as well

We installed satis-control-panel for using it with composer.
It look like it's easier to have it using https unless you want to always have ""secure-http": "false"" in the composer.lock.
So we put the site under SSL with a self-signed cert but now is the thing : the node server.js is not able to handle https on requests. So either you d'ont use async builds, either you have a Mixed content error :

2016-03-09 15_35_46-new notification

Is there a way where the node server can handle https ?

Can't add VCS repositories with ssh acces

When I want to add a git repository using ssh instead of http(s) the form denies it.
I guess this is because the regexp checks for http(s).
Satis still can manage git repositories over ssh.

Output from proccess

Processed build commands are not logged, only empty log files are created even after manual satis triggering there is an output in cli.

sh: 1: webpack-dev-server: not found

Hello! After installing the project with "composer create-project realshadow/satis-control-panel scp" and running the "npm run build" command, trying to run the "npm start' give me the "sh: 1: webpack-dev-server: not found" error.
Inspecting the package.json file, I could see the command (npm start) mapping to the "webpack-dev-server (...)'.

The package assumes the environment to have a global installation of its dependencies? If yes, I think it does not seem interesting.

Has anyone faced with this problem?

npm run server

[root@localhost satis-control-panel]# npm run server

> @ server /var/www/vhosts/satis.example.com/satis-control-panel
> node node/server.js


fs.js:439
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^
Error: ENOENT, no such file or directory ''
    at Object.fs.openSync (fs.js:439:18)
    at Object.fs.readFileSync (fs.js:290:15)
    at Object.<anonymous> (/var/www/vhosts/satis.example.com/satis-control-panel/node/server.js:11:15)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:935:3
npm ERR! weird error 8
npm ERR! not ok code 0
[root@localhost satis-control-panel]# node -v
v0.10.42
[root@localhost satis-control-panel]# npm -v
1.3.6

Confusion about public/private

When ever I hit the build button, I get a json file for public and private created in my storage/app folder, but nothing under public/public or public/private folders.

Am I missing something? The only thing I can't get working here is the npm server, which I'm not interested in anyway for my production environment.

Permissions are fine, everything seemed to set up fine, I can access the control panel fine and add repos fine. When I hit build the only thing that doesn't happen is a resulting satis file that can be read from the browser.

Has anyone else come across this issue?

Class log does not exist error

Fatal error: Uncaught ReflectionException: Class log does not exist in /vagrant/satis-control-panel/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 741

I'm getting this error from a fresh install of this project running via a vagrant machine. Looking around, I see this error happens in Laravel for a myriad of reasons. Has this come up for any users of this project before?

The way to stop build process

What is the best way to stop build process? I've added too much ๐Ÿ“ฆ to build.

I'll just leave it here:

ps ax | grep "bin/satis build" | cut -b1-06 | xargs -t kill

Update Satis release

It seems satis-control-panel is currently composering in "version": "1.0.0-alpha2" of Satis.

As far as I can tell, this version is showing symptoms of #377 and was resolved with #378. It is trying to mirror all of packagist when I only want private repositories.

I have asked them to issue a new release where this bug has been fixed, 1.0.0-alpha3. I have updated locally and it seems to have fixed this issue, but I am not certain if it is compatible.

Type error: Argument 1 passed to App\Satis\ConfigManager::_addOrUpdatePackage() must be an instance of App\Satis\Collections\PackageCollection, null given

After installing the application, and attempted to add a public package (from packagist), I received this error;

Type error: Argument 1 passed to App\Satis\ConfigManager::_addOrUpdatePackage() must be an instance of App\Satis\Collections\PackageCollection, null given

As far as I can see, it appears that the \App\Satis\Model\Config returns a null for getRepositories.
Am I missing something in the configuration?

problem connecting to api

Hello i ve made alll my configuration but I end up with 404 not found for both the UI or a curl request to the api.

I m using apache2 to host statis-control-panel my apache virtual host configurations is

<VirtualHost *:9001> ServerAdmin webmaster@localhost ServerName satis DocumentRoot /var/www/satis ErrorLog ${APACHE_LOG_DIR}/error_satis.log CustomLog ${APACHE_LOG_DIR}/access_satis.log combined </VirtualHost>

with a symbolic link satis -> /opt/satis-control-panel/public/

Node server is working fine and can acces the UI at http://my.domain/control-panel

but i get a
POST http://my.domain:9001/control-panel/api/package 404 (Not Found)

missing documentation for webserver setup

I think it miss some infos about how to configure exactly your webserver.
How the DocumentRoot is setup ? some rewrite rules ? laravel specific setup ?

After many hours i ended up with a 404 on /api ans i feel a bit frustrated

Delete button confirmation

Minor feature request to add confirmation of delete repository & packagist cache or undo button or actions history at least.

It's not critical on development stage, but could be painfull on production phase.

Truncate ability

There would be great to have console command for unit tests to truncate all the data after use case complete:

  • truncate repositories
  • truncate packages
  • truncate cache files
  • truncate all

Error on install

When trying to install I eventually get an error

Running
composer create-project realshadow/satis-control-panel
Throws

PHP Fatal error:  Uncaught ReflectionException: Class log does not exist in /home/dlamers/satis-control-panel/vendor/laravel/framework/src/Illuminate/Container/Container.php:741
Stack trace:

It is thrown right after composer fires php artisan optimize

PHP version override

The project's composer.lock contains the following snippets:

    "platform": {
        "php": ">=5.5.9"
    },
    "platform-overrides": {
        "php": "5.5"
    }

The version override causes a little conflict when attempting to install, like so :)

wobble@etikis:~/web$ composer create-project realshadow/satis-control-panel satis
Installing realshadow/satis-control-panel (1.0.2)
  - Installing realshadow/satis-control-panel (1.0.2)
    Loading from cache

Created project in satis
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - This package requires php >=5.5.9 but your PHP version (5.5) does not satisfy that requirement.
  Problem 2
    - Installation request for classpreloader/classpreloader 3.0.0 -> satisfiable by classpreloader/classpreloader[3.0.0].
    - classpreloader/classpreloader 3.0.0 requires php >=5.5.9 -> your PHP version (5.6.11-1ubuntu3.1) overriden by "config.platform.php" version (5.5) does not satisfy that requirement.
  Problem 3
    - Installation request for laravel/framework v5.1.28 -> satisfiable by laravel/framework[v5.1.28].
    - laravel/framework v5.1.28 requires php >=5.5.9 -> your PHP version (5.6.11-1ubuntu3.1) overriden by "config.platform.php" version (5.5) does not satisfy that requirement.
  Problem 4
    - Installation request for symfony/filesystem v3.0.1 -> satisfiable by symfony/filesystem[v3.0.1].
    - symfony/filesystem v3.0.1 requires php >=5.5.9 -> your PHP version (5.6.11-1ubuntu3.1) overriden by "config.platform.php" version (5.5) does not satisfy that requirement.
  Problem 5
    - Installation request for symfony/yaml v3.0.1 -> satisfiable by symfony/yaml[v3.0.1].
    - symfony/yaml v3.0.1 requires php >=5.5.9 -> your PHP version (5.6.11-1ubuntu3.1) overriden by "config.platform.php" version (5.5) does not satisfy that requirement.
  Problem 6
    - laravel/framework v5.1.28 requires php >=5.5.9 -> your PHP version (5.6.11-1ubuntu3.1) overriden by "config.platform.php" version (5.5) does not satisfy that requirement.
    - barryvdh/laravel-ide-helper v2.1.2 requires illuminate/console 5.0.x|5.1.x|5.2.x -> satisfiable by laravel/framework[v5.1.28].
    - Installation request for barryvdh/laravel-ide-helper v2.1.2 -> satisfiable by barryvdh/laravel-ide-helper[v2.1.2].

Satis version was updated with errors

Satis version was updated and now control panel is not working properly:)

PHP Warning: require(/var/www/html/satis/bin/../vendor/composer/satis/src/bootstrap.php): failed to open stream: No such file or directory in /var/www/html/satis/bin/satis on line 7
PHP Fatal error: require(): Failed opening required '/var/www/html/satis/bin/../vendor/composer/satis/src/bootstrap.php' (include_path='.:/usr/share/php') in /var/www/html/satis/bin/satis on line 7

bootstrap file was removed in latest satis release

Input data should be trimmed

If you'll add package with trailing space - it will be added successfully but build will ignore this package.

Second issue that all this names will be registered as unique ones:

`realshadow/satis-control-panel`
`realshadow/satis-control-panel `
` realshadow/satis-control-panel    `

Types of `path` and `artifact` can't work because of URL validation

As the title states, the path (/local/path/to/repo) won't validate the with the URL validation when trying to use Path or Artifact types.

I'd recommend dropping the URL validation all together and let the user assume they are entering what they need. URL validation also currently requires a URL ending in .git, which precludes Mercurial repos from working.

Running `npm start`/`yarn start` throws a Webpack error

Hi,

Not sure if this is my configuration, but I've gone through all the steps in the README file, and I'm getting the following error when running yarn start on Node v7.10.0:

yarn start v0.21.2
$ webpack-dev-server --host 0.0.0.0 --port 9001 --hot
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.entry should be one of these:
   object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function
   The entry point(s) of the compilation.
   Details:
    * configuration.entry should be an object.
    * configuration.entry should be a string.
    * configuration.entry should NOT have duplicate items (items ## 1 and 2 are identical) ({
        "keyword": "uniqueItems",
        "dataPath": ".entry",
        "schemaPath": "#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems",
        "params": {
          "i": 2,
          "j": 1
        },
        "message": "should NOT have duplicate items (items ## 1 and 2 are identical)",
        "schema": true,
        "parentSchema": {
          "items": {
            "minLength": 1,
            "type": "string"
          },
          "minItems": 1,
          "type": "array",
          "uniqueItems": true
        },
        "data": [
          "/Users/adam/.nvm/versions/node/v7.10.0/lib/node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:9001",
          "webpack/hot/dev-server",
          "webpack/hot/dev-server",
          "./resources/assets/typescript/app.tsx",
          "./resources/assets/typescript/flux/components/ActionPanel.tsx",
          "./resources/assets/typescript/flux/components/FormElements.tsx",
          "./resources/assets/typescript/flux/components/Forms.tsx",
          "./resources/assets/typescript/flux/components/InfoPanel.tsx",
          "./resources/assets/typescript/flux/components/Modal.tsx",
          "./resources/assets/typescript/flux/components/Overlay.tsx",
          "./resources/assets/typescript/flux/components/Packages.tsx",
          "./resources/assets/typescript/flux/components/Repositories.tsx",
          "./resources/assets/typescript/flux/mixins/EventHandler.tsx",
          "./resources/assets/typescript/flux/mixins/Validation.tsx",
          "./resources/assets/typescript/helpers/Validator.ts"
        ]
      }).
      [non-empty string]
    * configuration.entry should be an instance of function
      function returning an entry object or a promise..
 - configuration.resolve.extensions[0] should not be empty.
error Command failed with exit code 1.

Node compatible versions and New install error

Hello I'm trying to install using composer. but there's an error in installation.

  • RHEL 7
  • Node 14
  • PHP 7.2

> node_modules/.bin/gulp init
fs.js:41
} = primordials;
    ^

ReferenceError: primordials is not defined
    at fs.js:41:5
    at req_ (/apps/www/php7_desenvolvimento/html/aplicacao/[--stability-dev]/node_modules/natives/index.js:143:24)
    at Object.req [as require] (/apps/www/php7_desenvolvimento/html/aplicacao/[--stability-dev]/node_modules/natives/index.js:55:10)
    at Object.<anonymous> (/apps/www/php7_desenvolvimento/html/aplicacao/[--stability-dev]/node_modules/graceful-fs/fs.js:1:37)
    at Module._compile (internal/modules/cjs/loader.js:1076:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:941:32)
    at Function.Module._load (internal/modules/cjs/loader.js:782:14)
    at Module.require (internal/modules/cjs/loader.js:965:19)
    at require (internal/modules/cjs/helpers.js:88:18)
Script node_modules/.bin/gulp init handling the post-install-cmd event returned with error code 1

Which Node version should I use?

UI Screenshots

would be great to get a feeling of this UI with some screenshots in the README

Missing features

Hey guys,

are there any missing features you would like to see added in the near future?

Error when trying to build repository

Every time when trying to build added VCS exception raising:

[Composer\Json\JsonValidationException]

The json config file does not match the expected JSON schema

Exception trace:
() at /home/ell/Development/satis-control-panel/vendor/composer/satis/src/Composer/Satis/Command/BuildCommand.php:282
Composer\Satis\Command\BuildCommand->check() at /home/ell/Development/satis-control-panel/vendor/composer/satis/src/Composer/Satis/Command/BuildCommand.php:128
Composer\Satis\Command\BuildCommand->execute() at /home/ell/Development/satis-control-panel/vendor/symfony/console/Command/Command.php:256
Symfony\Component\Console\Command\Command->run() at /home/ell/Development/satis-control-panel/vendor/symfony/console/Application.php:841
Symfony\Component\Console\Application->doRunCommand() at /home/ell/Development/satis-control-panel/vendor/symfony/console/Application.php:189
Symfony\Component\Console\Application->doRun() at /home/ell/Development/satis-control-panel/vendor/composer/satis/src/Composer/Satis/Console/Application.php:52
Composer\Satis\Console\Application->doRun() at /home/ell/Development/satis-control-panel/vendor/symfony/console/Application.php:120
Symfony\Component\Console\Application->run() at /home/ell/Development/satis-control-panel/bin/satis:26

build [--repository-url [REPOSITORY-URL]] [--no-html-output] [--skip-errors] [--] [] [] []...

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.