From 94ada85840fd4d6bf1eb22372889e477c878dbc3 Mon Sep 17 00:00:00 2001 From: Anish Karandikar Date: Wed, 23 May 2018 17:55:01 -0400 Subject: [PATCH] chore(ci): Add script to autogenerate repo listing in README --- .gitignore | 2 + .travis.yml | 5 +- etc/README.tmpl.md | 171 ++++++++++++++++++++++++++++++++++++++++ etc/backend-repos.yaml | 60 ++++++++++++++ etc/frontend-repos.yaml | 39 +++++++++ etc/push.sh | 18 +++++ etc/update-readme.js | 72 +++++++++++++++++ package.json | 2 + 8 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 etc/README.tmpl.md create mode 100644 etc/backend-repos.yaml create mode 100644 etc/frontend-repos.yaml create mode 100755 etc/push.sh create mode 100644 etc/update-readme.js diff --git a/.gitignore b/.gitignore index 9b3fe91ad..9112d4716 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ logs npm-debug.log* yarn-debug.log* yarn-error.log* +package-lock.json +yarn.lock # Runtime data pids diff --git a/.travis.yml b/.travis.yml index 8a08305de..2daf28993 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: - - "7" + - "10" script: - - newman run api/Conduit.postman_collection.json -e api/Conduit.postman_integration_test_environment.json --global-var "EMAIL=$CONDUIT_EMAIL" --global-var "PASSWORD=$CONDUIT_PASSWORD" + - cd etc && ./push.sh + diff --git a/etc/README.tmpl.md b/etc/README.tmpl.md new file mode 100644 index 000000000..307d4f97e --- /dev/null +++ b/etc/README.tmpl.md @@ -0,0 +1,171 @@ +# ![RealWorld Example Applications](media/realworld.png) + +### Stay on the bleeding edge — [join our Gitter room!](https://gitter.im/realworld-dev/main) 🎉 + +[![Travis](https://img.shields.io/travis/gothinkster/realworld.svg)](https://travis-ci.org/gothinkster/realworld) [![Gitter](https://img.shields.io/gitter/room/realworld-dev/main.svg)](https://gitter.im/realworld-dev/main) [![Twitter](https://img.shields.io/twitter/follow/gothinkster.svg?style=social&label=Follow)](https://twitter.com/gothinkster) + +

+ +

+ + + +### See how *the exact same* Medium.com clone (called [Conduit](https://demo.realworld.io)) is built using any of our supported [frontends](#frontends) and [backends](#backends). Yes, you can mix and match them, because **they all adhere to the same [API spec](spec/)** 😮😎 + +While most "todo" demos provide an excellent cursory glance at a framework's capabilities, they typically don't convey the knowledge & perspective required to actually build _real_ applications with it. + +RealWorld solves this by allowing you to choose any frontend (React, Angular 2, & more) and any backend (Node, Django, & more) and see how they power a real world, beautifully designed fullstack app called "[Conduit](https://demo.realworld.io)". + +*Read the [full blog post announcing RealWorld on Medium.](https://medium.com/@ericsimons/introducing-realworld-6016654d36b5)* + + +# Frontends +>_Sorted by popularity every 24 hours._ + +## INSERT_FRONTEND_REPOS + +Work In Progress: **[Ember](https://github.com/gothinkster/realworld/issues/22) | [React+Relay](https://github.com/gothinkster/realworld/issues/48) | [ClojureScript](https://github.com/gothinkster/realworld/issues/61) | [Mithril](https://github.com/gothinkster/realworld/issues/69) | [Vanilla JS (Web Components)](https://github.com/gothinkster/realworld/issues/111) | [Angular+NgRx+nx](https://github.com/gothinkster/realworld/issues/178) | [Blazor (ASP.NET Core + Web Assembly)](https://github.com/torhovland/blazor-realworld-example-app)** + +# Backends +>_Sorted by popularity every 24 hours._ + +## INSERT_BACKEND_REPOS + +Work In Progress: **[Clojure](https://github.com/gothinkster/realworld/issues/57) | [Crystal + Kemal](https://github.com/gothinkster/realworld/issues/112) | [Dotnet Core (C#)](https://github.com/gothinkster/realworld/issues/31) | [Dropwizard](https://github.com/gothinkster/realworld/issues/95) | [Falcon + GAE](https://github.com/gothinkster/realworld/issues/59) | [Firebase + GCP Cloud](https://github.com/gothinkster/realworld/issues/21) | [Go + Gorilla mux](https://github.com/gothinkster/realworld/issues/99) | [Go + net/http](https://github.com/gothinkster/realworld/issues/45) | [Haskell / Servant](https://github.com/gothinkster/realworld/issues/73) | [Loopback 3.0](https://github.com/gothinkster/realworld/issues/105) | [Nim](https://github.com/gothinkster/realworld/issues/60) | [Node + GraphQL](https://github.com/gothinkster/realworld/issues/46) | [Node (Lambda + DynamoDB)](https://github.com/gothinkster/realworld/issues/37) | [Phalcon](https://github.com/gothinkster/realworld/issues/88) | [Spring (w/ Spring Boot)](https://github.com/gothinkster/realworld/issues/55) | [Symfony](https://github.com/gothinkster/realworld/issues/66)** + + +# Mobile + +Work In Progress: **[React Native](https://github.com/gothinkster/realworld/issues/10) | [Ionic 2+](https://github.com/gothinkster/realworld/issues/16) | [Xamarin](https://github.com/gothinkster/realworld/issues/70)** + +# Fullstack + +_Since these implementations are reponsible for the entire stack, they obviously cannot be mixed and matched but they still adhere to the same functionality & UX specs._ + +Work In Progress: **[Meteor]() | [Ruby Hyperloop]() | [Firebase](https://github.com/gothinkster/realworld/issues/199)** + +# Create a new stack + +[![Create a new stack](media/upcoming_stacks.png)](/spec) + +### Know any of these frameworks (or one that isn't listed)?
[**Create a new framework implementation >>>**](/spec) + +Or you can [view upcoming stacks (WIPs)](https://github.com/gothinkster/realworld/issues?q=is%3Aopen+is%3Aissue+label%3Awip) + +Note: All stacks that are a WIP are experimental and incomplete. + +Don't expect everything to work perfectly out of the box! + +
+ +# How do I get up & running? + +Simply follow the instructions in the README of whatever frontend and/or backend repo's you want to get up and running. + +### Can you teach me how to build each stack from scratch? + +Yup! We've built step-by-step tutorials for all of our stacks that teach you how to go from `git init` all the way to the production ready application. [**Start learning now >>>**](https://thinkster.io/tutorials/fullstack) + +
+ +# Community created resources + +Forks, tutorials, workshops, and other resources based on the RealWorld project: + +- [**React+Redux / Node testing workshop**](https://github.com/kentcdodds/testing-workshop) by [**Kent C. Dodds**](https://github.com/kentcdodds) + - Example repo showing the React+Redux and Node stacks working together w/ TDD + - Live recording of his workshop is [**available on YouTube**](https://www.youtube.com/watch?v=DdqiXcYDv-8) +- [**A Real-World Comparison of Front-End Frameworks with Benchmarks**](https://medium.freecodecamp.org/a-real-world-comparison-of-front-end-frameworks-with-benchmarks-e1cb62fd526c) by [**Jacek Schae**](https://medium.freecodecamp.org/@jacekschae) + - Medium post comparing performance of various [RealWorld](https://realworld.io/) frontends +- [**RealWorld React/NodeJS E2E Tests**](https://github.com/anishkny/realworld-e2e-test) by [**Anish Karandikar**](https://github.com/anishkny) + - A repo showing how to wire [React](https://github.com/gothinkster/react-redux-realworld-example-app) frontend with [NodeJS](https://github.com/gothinkster/node-express-realworld-example-app) backend for a RealWorld fullstack + - Includes E2E integration tests that use [Chrome Puppeteer](https://github.com/GoogleChrome/puppeteer) and [Mocha](https://mochajs.org) and work with CI systems like [Travis CI](https://travis-ci.org/anishkny/realworld-e2e-test) and [CircleCI](https://circleci.com/gh/anishkny/realworld-e2e-test) + - Also demonstrates usage of [Greenkeeper](https://greenkeeper.io) for automatic dependency updates and [Snyk](https://snyk.io/) for vulnerability monitoring +- Performance comparisons: + - [A Real-World Comparison of Front-End Frameworks with Benchmarks](https://medium.freecodecamp.org/a-real-world-comparison-of-front-end-frameworks-with-benchmarks-e1cb62fd526c) + - [A Real-World Comparison of Front-End Frameworks with Benchmarks (2018 update)](https://medium.freecodecamp.org/a-real-world-comparison-of-front-end-frameworks-with-benchmarks-2018-update-e5760fb4a962) + +
+ +# Learn more + +- ["Introducing RealWorld 🙌"](https://medium.com/@ericsimons/introducing-realworld-6016654d36b5) by Eric Simons +- Every tutorial is built against the same [API spec](api/) to ensure modularity of every frontend & backend +- Every frontend utilizes the same hand crafted [Bootstrap 4 theme](https://github.com/gothinkster/conduit-bootstrap-template) for identical UI/UX +- There is a hosted version of the backend API available for public usage, no API keys required +- Interested in creating a new RealWorld stack? View our [starter guide & spec](/spec) + +
+ + +# Who made this? + +RealWorld would not be possible without the [open source community](#special-thanks-to) continuously helping push the project forward. In addition, we have a core project team composed of: + +#### [Eric Simons](https://twitter.com/ericsimons40) - Founder/Lead + + + +Eric is a Software Engineer, UI Designer, and author of many technical books & tutorials. He oversees the project direction, maintenance and organizes the planning and development efforts of the team. + + +#### [Albert Pai](https://twitter.com/iamalbertpai) - Founder/Lead + + + +Albert is a Software Engineer, DevOps ninja, and author of many technical books & tutorials. He oversees the project direction, maintenance and organizes the planning and development efforts of the team. + +#### [Thinkster](https://twitter.com/gothinkster) - Funding/Support + + + +[Thinkster](https://thinkster.io) creates high quality resources that help Javascript developers succeed. The RealWorld project wouldn't exist without their funding, so please consider investing in [a Pro subscription](https://thinkster.io/pro) to help support us! + + +#### [James Brewer](https://twitter.com/brwr_) - Admin + + + +James is a Software Engineer at Square and a contributor to the Django project. He created & maintains the RW Django codebase and continually provides guidance for the RealWorld project itself. + +#### [Anish Karandikar](https://github.com/anishkny) - Admin + + + +MathWorker, ex-Google, ex-Computational Fluid Dynamicist, forever lover of tech & humanities ❤️ + + +#### [Sandeesh S.](https://github.com/SandeeshS) - Admin + + + +Full stack developer, Laravel enthusiast, Digital marketing specialist and an avid gamer. + + +#### [Cameron Chapman](https://github.com/Cameron-C-Chapman) - Admin + + + +Cameron Chapman is a Software Engineer at FanThreeSixty. He's an open source enthusiast and is helping to teach a local web development boot camp at Kansas University. + + + +## Special thanks to... + +RealWorld wouldn't be possible without the help of the open source community reviewing codebases, creating new app implementations, and many other tasks that help push this project forward. We especially appreciate the OSS leaders who have helped contribute to RealWorld: + +- **Dan Abramov** (creator of Redux) for helping [spark the initial idea](https://twitter.com/dan_abramov/status/692009757775896577), [getting the Redux community involved](https://github.com/reactjs/redux/issues/1353), as well as graciously taking the time to provide feedback on the Redux codebase +- **Max Lynch** (creator of Ionic) for taking the time to provide guidance in the early days of this project +- **Addy Osmani** (creator of TodoMVC) for helping [spark the initial idea](https://twitter.com/addyosmani/status/762828483433144320) and his amazing work with TodoMVC +- **TodoMVC** ([team & contributors](https://github.com/tastejs/todomvc#team)) for their exemplary & successful work; their project & org has been an invaluable analogy for us as we've built out RealWorld +- **James Brewer** (docs contributor to Django) for countless brainstorming sessions, helping name this project, and creating the Django codebase + tutorial + + + + +# License +All of the codebases are **MIT licensed** unless otherwise specified. + +
+ +[![Brought to you by Thinkster](media/end.png)](https://thinkster.io) diff --git a/etc/backend-repos.yaml b/etc/backend-repos.yaml new file mode 100644 index 000000000..599fb3e3d --- /dev/null +++ b/etc/backend-repos.yaml @@ -0,0 +1,60 @@ +- title: Node / Express + repo: gothinkster/node-express-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/node-express-realworld-example-app/master/project-logo.png +- title: Laravel + repo: gothinkster/laravel-realworld-example-app + logo: https://github.com/gothinkster/laravel-realworld-example-app/blob/master/logo.png +- title: Django + repo: gothinkster/django-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/django-realworld-example-app/master/project-logo.png +- title: ASP.NET Core + repo: gothinkster/aspnetcore-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/aspnetcore-realworld-example-app/master/logo.png +- title: Elixir + Phoenix + repo: gothinkster/elixir-phoenix-realworld-example-app + logo: https://github.com/gothinkster/elixir-phoenix-realworld-example-app/blob/master/logo.png +- title: Rails + repo: gothinkster/rails-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/rails-realworld-example-app/master/project-logo.png +- title: Kotlin / Spring + repo: gothinkster/kotlin-spring-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/kotlin-spring-realworld-example-app/master/kotlin-spring.png +- title: Flask + repo: gothinkster/flask-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/flask-realworld-example-app/master/image.png +- title: Slim + repo: gothinkster/slim-php-realworld-example-app + logo: https://github.com/gothinkster/slim-php-realworld-example-app/blob/master/logo.png +- title: Spring + repo: gothinkster/spring-boot-realworld-example-app + logo: https://github.com/gothinkster/spring-boot-realworld-example-app/raw/master/example-logo.png +- title: CakePHP + repo: gothinkster/cakephp-realworld-example-app + logo: https://github.com/gothinkster/cakephp-realworld-example-app/raw/master/logo.png +- title: Koa / Knex + repo: gothinkster/koa-knex-realworld-example + logo: https://github.com/gothinkster/koa-knex-realworld-example/raw/master/logo.png +- title: Go + Gin + repo: gothinkster/golang-gin-realworld-example-app + logo: https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/logo.png +- title: Rust + repo: gothinkster/rust-realworld-example-app + logo: https://github.com/gothinkster/rust-realworld-example-app/raw/master/logo.png +- title: GCP Cloud Functions + Datastore + repo: gothinkster/gcp-datastore-cloud-functions-realworld-example-app + logo: https://github.com/gothinkster/gcp-datastore-cloud-functions-realworld-example-app/raw/master/logo.png +- title: Hapi.js + repo: gothinkster/hapijs-realworld-example-app + logo: https://github.com/gothinkster/hapijs-realworld-example-app/blob/master/.github/project-logo.png +- title: QEWD.js + repo: gothinkster/QEWD-realworld-example-app + logo: https://cloud.githubusercontent.com/assets/556934/25587724/182f95fc-2e5a-11e7-83db-1541c1bee128.png +- title: Moleculer + repo: gothinkster/moleculer-node-realworld-example-app + logo: https://github.com/gothinkster/moleculer-node-realworld-example-app/blob/master/rw-logo.png +- title: F# + repo: gothinkster/fsharp-realworld-example-app + logo: https://github.com/gothinkster/fsharp-realworld-example-app/blob/master/logo.png +- title: Scala & Play Framework + repo: gothinkster/scala-play-realworld-example-app + logo: https://github.com/gothinkster/scala-play-realworld-example-app/blob/master/logo.png diff --git a/etc/frontend-repos.yaml b/etc/frontend-repos.yaml new file mode 100644 index 000000000..6b087ac00 --- /dev/null +++ b/etc/frontend-repos.yaml @@ -0,0 +1,39 @@ +- title: React / Redux + repo: gothinkster/react-redux-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/react-redux-realworld-example-app/master/project-logo.png +- title: Elm + repo: rtfeldman/elm-spa-example + logo: https://cloud.githubusercontent.com/assets/556934/25448178/3e7dc5c0-2a7d-11e7-8069-06da5169dae6.png +- title: Angular + repo: gothinkster/angular-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/angular2-realworld-example-app/master/logo.png +- title: React / MobX + repo: gothinkster/react-mobx-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/react-mobx-realworld-example-app/master/project-logo.png +- title: AngularJS + repo: gothinkster/angularjs-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/angularjs-realworld-example-app/master/project-logo.png +- title: Vue + repo: gothinkster/vue-realworld-example-app + logo: https://github.com/gothinkster/vue-realworld-example-app/blob/master/static/rwv-logo.png +- title: Svelte / Sapper + repo: sveltejs/realworld + logo: https://github.com/sveltejs/realworld/blob/master/logo.png +- title: ClojureScript + Keechma + repo: gothinkster/clojurescript-keechma-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/clojurescript-keechma-realworld-example-app/master/logo.png +- title: ClojureScript + re-frame + repo: gothinkster/clojurescript-reframe-realworld-example-app + logo: https://cloud.githubusercontent.com/assets/556934/25448267/85369fdc-2a7d-11e7-9613-ab5ce5e1800f.png +- title: AppRun + repo: gothinkster/apprun-realworld-example-app + logo: https://github.com/gothinkster/apprun-realworld-example-app/blob/master/logo.png +- title: Crizmas MVC + repo: gothinkster/crizmas-mvc-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/crizmas-mvc-realworld-example-app/master/crizmas.png +- title: Aurelia + repo: gothinkster/aurelia-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/aurelia-realworld-example-app/master/logo.png +- title: Dojo 2 + repo: gothinkster/dojo2-realworld-example-app + logo: https://raw.githubusercontent.com/gothinkster/dojo2-realworld-example-app/master/logo.png diff --git a/etc/push.sh b/etc/push.sh new file mode 100755 index 000000000..17dd796bc --- /dev/null +++ b/etc/push.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -x +set -e + +## Change into this script's folder +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $DIR + +node ./update-readme.js + +git --version +git config --global user.email "travis@travis-ci.org" +git config --global user.name "Travis CI" +git checkout -b next +git add README.md +git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" +git remote add origin-next https://${GH_TOKEN}@github.com/anishkny/realworld.git +git push --quiet --set-upstream origin-next next diff --git a/etc/update-readme.js b/etc/update-readme.js new file mode 100644 index 000000000..c6839fc70 --- /dev/null +++ b/etc/update-readme.js @@ -0,0 +1,72 @@ +#!/usr/bin/env node + +const axios = require('axios'); +const fs = require('fs'); +const jsYaml = require('js-yaml'); + +const README_TEMPLATE_FILE = 'README.tmpl.md'; +const README_TARGET_FILE = '../README.md'; +const FRONTEND_PLACEHOLDER = 'INSERT_FRONTEND_REPOS'; +const BACKEND_PLACEHOLDER = 'INSERT_BACKEND_REPOS'; +const FRONTEND_REPOS = jsYaml.safeLoad(fs.readFileSync('frontend-repos.yaml', 'utf8')); +const BACKEND_REPOS = jsYaml.safeLoad(fs.readFileSync('backend-repos.yaml', 'utf8')); + +axios.defaults.headers.common['Authorization'] = `token ${process.env.GH_TOKEN}`; + +(async () => { + await main(); +})(); + +async function main() { + + const input = fs.readFileSync(README_TEMPLATE_FILE, 'utf8').split("\n"); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i].indexOf(FRONTEND_PLACEHOLDER) > -1) { + output.push(...(await getSortedTable(FRONTEND_REPOS))); + } else if (input[i].indexOf(BACKEND_PLACEHOLDER) > -1) { + output.push(...(await getSortedTable(BACKEND_REPOS))); + } else { + output.push(input[i]); + } + } + fs.writeFileSync(README_TARGET_FILE, output.join('\n')); + console.log(`Wrote output to file: [${README_TARGET_FILE}]`); + +} + +async function getSortedTable(repos) { + + // Get sorted repos by stargazers_count + for (let i = 0; i < repos.length; ++i) { + const stargazers_count = + (await axios.get(`https://api.github.com/repos/${repos[i].repo}`)) + .data.stargazers_count; + repos[i].stargazers_count = stargazers_count; + } + repos = repos.sort((a, b) => b.stargazers_count - a.stargazers_count); + + // Output sorted table + const output = [ + '| 🥇 | 🥈 | 🥉 |', + '| :---: | :---: | :---: |', + ]; + let string = ''; + for (let i = 0; i < repos.length; ++i) { + string += `| [**${repos[i].title}**
` + + `![${repos[i].title}](${repos[i].logo}) ` + + `![Star](https://img.shields.io/github/stars/${repos[i].repo}.svg?style=social&label=Star) ` + + `![Fork](https://img.shields.io/github/forks/${repos[i].repo}.svg?style=social&label=Fork)]` + + `(https://github.com/${repos[i].repo})`; + if (!((i + 1) % 3)) { + output.push(string); + string = ''; + } + } + output.push(string); + return output; +} + +process.on('unhandledRejection', (reason, p) => { + console.log('Unhandled Rejection at:', p, 'reason:', reason); +}); diff --git a/package.json b/package.json index 5c18aa5d5..ef2182479 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ }, "homepage": "https://github.com/gothinkster/realworld#readme", "devDependencies": { + "axios": "^0.18.0", + "js-yaml": "^3.11.0", "newman": "^3.5.2" } }