Git Product home page Git Product logo

github4s's Introduction

Join the chat at https://gitter.im/47degrees/github4s codecov.io Maven Central License Latest version GitHub Issues

Github4s

Github4s is a GitHub API wrapper written in Scala.

Installation

To get started with SBT, simply add the following to your build.sbt file.

libraryDependencies += "com.47deg" %% "github4s" % "0.33.3"

Github4s in the wild

If you wish to add your library here please consider a PR to include it in the list below.

scala-exercises scala-exercises Scala Exercises is an Open Source project for learning different technologies based in the Scala Programming Language.
dashing Dashing is a collection of dashboards to monitor the health of an open source organization.
cla-bot Bot making sure external contributors sign a CLA.

Copyright

Github4s is designed and developed by 47 Degrees

Copyright (C) 2016-2022 47 Degrees. http://47deg.com

github4s's People

Contributors

47degdev avatar 47erbot avatar adrianrafo avatar alejandrohdezma avatar aleksandr-vin avatar anamariamv avatar antoniomateogomez avatar bcreaney avatar benfradet avatar bond15 avatar calvellido avatar daenyth avatar duanebester avatar fedefernandez avatar georgeorfanidi avatar grburst avatar jesusmtnez avatar juanpedromoreno avatar kusaeva avatar lloydmeta avatar loonydev avatar mfirry avatar mkobzik avatar nicoulaj avatar pepegar avatar reimai avatar scala-steward avatar sloshy avatar yarektyshchenko avatar zachkirlew 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  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

github4s's Issues

Enrich repository model

We need to enrich the repository class in order to get an enhanced approximation to the value returned by Github (specially to include watchers, stars and forks):

{
  "id": 23613922,
  "name": "scala-exercises",
  "full_name": "scala-exercises/scala-exercises",
  "owner": {
    "login": "scala-exercises",
    "id": 17570897,
    "avatar_url": "https://avatars.githubusercontent.com/u/17570897?v=3",
    "gravatar_id": "",
    "url": "https://api.github.com/users/scala-exercises",
    "html_url": "https://github.com/scala-exercises",
    "followers_url": "https://api.github.com/users/scala-exercises/followers",
    "following_url": "https://api.github.com/users/scala-exercises/following{/other_user}",
    "gists_url": "https://api.github.com/users/scala-exercises/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/scala-exercises/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/scala-exercises/subscriptions",
    "organizations_url": "https://api.github.com/users/scala-exercises/orgs",
    "repos_url": "https://api.github.com/users/scala-exercises/repos",
    "events_url": "https://api.github.com/users/scala-exercises/events{/privacy}",
    "received_events_url": "https://api.github.com/users/scala-exercises/received_events",
    "type": "Organization",
    "site_admin": false
  },
  "private": false,
  "html_url": "https://github.com/scala-exercises/scala-exercises",
  "description": "The easy way to learn Scala.",
  "fork": false,
  "url": "https://api.github.com/repos/scala-exercises/scala-exercises",
  "forks_url": "https://api.github.com/repos/scala-exercises/scala-exercises/forks",
  "keys_url": "https://api.github.com/repos/scala-exercises/scala-exercises/keys{/key_id}",
  "collaborators_url": "https://api.github.com/repos/scala-exercises/scala-exercises/collaborators{/collaborator}",
  "teams_url": "https://api.github.com/repos/scala-exercises/scala-exercises/teams",
  "hooks_url": "https://api.github.com/repos/scala-exercises/scala-exercises/hooks",
  "issue_events_url": "https://api.github.com/repos/scala-exercises/scala-exercises/issues/events{/number}",
  "events_url": "https://api.github.com/repos/scala-exercises/scala-exercises/events",
  "assignees_url": "https://api.github.com/repos/scala-exercises/scala-exercises/assignees{/user}",
  "branches_url": "https://api.github.com/repos/scala-exercises/scala-exercises/branches{/branch}",
  "tags_url": "https://api.github.com/repos/scala-exercises/scala-exercises/tags",
  "blobs_url": "https://api.github.com/repos/scala-exercises/scala-exercises/git/blobs{/sha}",
  "git_tags_url": "https://api.github.com/repos/scala-exercises/scala-exercises/git/tags{/sha}",
  "git_refs_url": "https://api.github.com/repos/scala-exercises/scala-exercises/git/refs{/sha}",
  "trees_url": "https://api.github.com/repos/scala-exercises/scala-exercises/git/trees{/sha}",
  "statuses_url": "https://api.github.com/repos/scala-exercises/scala-exercises/statuses/{sha}",
  "languages_url": "https://api.github.com/repos/scala-exercises/scala-exercises/languages",
  "stargazers_url": "https://api.github.com/repos/scala-exercises/scala-exercises/stargazers",
  "contributors_url": "https://api.github.com/repos/scala-exercises/scala-exercises/contributors",
  "subscribers_url": "https://api.github.com/repos/scala-exercises/scala-exercises/subscribers",
  "subscription_url": "https://api.github.com/repos/scala-exercises/scala-exercises/subscription",
  "commits_url": "https://api.github.com/repos/scala-exercises/scala-exercises/commits{/sha}",
  "git_commits_url": "https://api.github.com/repos/scala-exercises/scala-exercises/git/commits{/sha}",
  "comments_url": "https://api.github.com/repos/scala-exercises/scala-exercises/comments{/number}",
  "issue_comment_url": "https://api.github.com/repos/scala-exercises/scala-exercises/issues/comments{/number}",
  "contents_url": "https://api.github.com/repos/scala-exercises/scala-exercises/contents/{+path}",
  "compare_url": "https://api.github.com/repos/scala-exercises/scala-exercises/compare/{base}...{head}",
  "merges_url": "https://api.github.com/repos/scala-exercises/scala-exercises/merges",
  "archive_url": "https://api.github.com/repos/scala-exercises/scala-exercises/{archive_format}{/ref}",
  "downloads_url": "https://api.github.com/repos/scala-exercises/scala-exercises/downloads",
  "issues_url": "https://api.github.com/repos/scala-exercises/scala-exercises/issues{/number}",
  "pulls_url": "https://api.github.com/repos/scala-exercises/scala-exercises/pulls{/number}",
  "milestones_url": "https://api.github.com/repos/scala-exercises/scala-exercises/milestones{/number}",
  "notifications_url": "https://api.github.com/repos/scala-exercises/scala-exercises/notifications{?since,all,participating}",
  "labels_url": "https://api.github.com/repos/scala-exercises/scala-exercises/labels{/name}",
  "releases_url": "https://api.github.com/repos/scala-exercises/scala-exercises/releases{/id}",
  "deployments_url": "https://api.github.com/repos/scala-exercises/scala-exercises/deployments",
  "created_at": "2014-09-03T09:14:41Z",
  "updated_at": "2016-06-19T20:24:00Z",
  "pushed_at": "2016-06-20T14:12:11Z",
  "git_url": "git://github.com/scala-exercises/scala-exercises.git",
  "ssh_url": "[email protected]:scala-exercises/scala-exercises.git",
  "clone_url": "https://github.com/scala-exercises/scala-exercises.git",
  "svn_url": "https://github.com/scala-exercises/scala-exercises",
  "homepage": "https://scala-exercises.org",
  "size": 10585,
  "stargazers_count": 428,
  "watchers_count": 428,
  "language": "Scala",
  "has_issues": true,
  "has_downloads": true,
  "has_wiki": false,
  "has_pages": true,
  "forks_count": 193,
  "mirror_url": null,
  "open_issues_count": 27,
  "forks": 193,
  "open_issues": 27,
  "watchers": 428,
  "default_branch": "master",
  "organization": {
    "login": "scala-exercises",
    "id": 17570897,
    "avatar_url": "https://avatars.githubusercontent.com/u/17570897?v=3",
    "gravatar_id": "",
    "url": "https://api.github.com/users/scala-exercises",
    "html_url": "https://github.com/scala-exercises",
    "followers_url": "https://api.github.com/users/scala-exercises/followers",
    "following_url": "https://api.github.com/users/scala-exercises/following{/other_user}",
    "gists_url": "https://api.github.com/users/scala-exercises/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/scala-exercises/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/scala-exercises/subscriptions",
    "organizations_url": "https://api.github.com/users/scala-exercises/orgs",
    "repos_url": "https://api.github.com/users/scala-exercises/repos",
    "events_url": "https://api.github.com/users/scala-exercises/events{/privacy}",
    "received_events_url": "https://api.github.com/users/scala-exercises/received_events",
    "type": "Organization",
    "site_admin": false
  },
  "network_count": 193,
  "subscribers_count": 54
}

Unify tests

Currently there's a lot of duplicity between JS and JVM tests. We should parameterize the current tests and put them in the shared project; to have the actual tests in both platforms just "filling the gaps".

Random issues on Travis

We have a lot of errored builds in Travis due to inactivity when executing:

  • Fast optimizing /home/travis/build/47deg/github4s/github4s/js/target/scala-2.12/github4s-test-fastopt.js

See an example here

Create package object to handle current imports

There are a lot of imports needed to perform actions on the API (i.e.: Interpreters.scala). We should have a package object to handle these as type aliases, so users can just import that to get started using them.

Issues using the combined status API

I'm having some issues with retrieving data from some of our private repos. I'm not sure what the cause might be.

import cats.Id
import cats.implicits._
import github4s.Github
import github4s.Github._
import github4s.GithubResponses.{GHException, GHResponse, UnexpectedException}
import github4s.free.domain._
import github4s.jvm.Implicits._
import scalaj.http._

val github: Github = Github(sys.env.get("GITHUB_TOKEN"))
val response = github.repos.getCombinedStatus("Equiem", "webhooks", "595a30440c9473e7c4fbdb827127c6ab02995561").exec[Id, HttpResponse[String]]()
// response: cats.Id[github4s.GithubResponses.GHResponse[github4s.free.domain.CombinedStatus]] = Left(github4s.GithubResponses$JsonParsingException: Int:
DownField(id),DownArray,DownField(statuses))

Full stack trace:

github4s.GithubResponses$JsonParsingException: Int: DownField(id),DownArray,DownField(statuses)
        at github4s.HttpRequestBuilderExtensionJVM.$anonfun$decodeEntity$1(HttpRequestBuilderExtensionJVM.scala:90)
        at cats.syntax.EitherOps$.bimap$extension(either.scala:129)
        at github4s.HttpRequestBuilderExtensionJVM.decodeEntity(HttpRequestBuilderExtensionJVM.scala:91)
        at github4s.HttpRequestBuilderExtensionJVM.decodeEntity$(HttpRequestBuilderExtensionJVM.scala:88)
        at github4s.jvm.Implicits$.decodeEntity(Implicits.scala:21)
        at github4s.HttpRequestBuilderExtensionJVM$$anon$1.$anonfun$run$1(HttpRequestBuilderExtensionJVM.scala:34)
        at github4s.HttpRequestBuilderExtensionJVM.toEntity(HttpRequestBuilderExtensionJVM.scala:79)
        at github4s.HttpRequestBuilderExtensionJVM.toEntity$(HttpRequestBuilderExtensionJVM.scala:74)
        at github4s.jvm.Implicits$.toEntity(Implicits.scala:21)
        at github4s.HttpRequestBuilderExtensionJVM$$anon$1.$anonfun$runMap$4(HttpRequestBuilderExtensionJVM.scala:69)
        at github4s.IdInstances$$anon$4.capture(Implicits.scala:73)
        at github4s.HttpRequestBuilderExtensionJVM$$anon$1.runMap(HttpRequestBuilderExtensionJVM.scala:69)
        at github4s.HttpRequestBuilderExtensionJVM$$anon$1.run(HttpRequestBuilderExtensionJVM.scala:34)
        at github4s.HttpClient.get(HttpClient.scala:124)
        at github4s.api.Repos.getStatus(Repos.scala:244)
        at github4s.free.interpreters.Interpreters$$anon$1.$anonfun$apply$1(Interpreters.scala:106)
        at cats.data.Kleisli.$anonfun$map$1(Kleisli.scala:19)
        at cats.data.KleisliFlatMap.$anonfun$tailRecM$2(Kleisli.scala:324)
        at cats.package$$anon$1.tailRecM(package.scala:41)
        at github4s.IdInstances$$anon$2.tailRecM(Implicits.scala:87)
        at cats.data.KleisliFlatMap.$anonfun$tailRecM$1(Kleisli.scala:324)
        at github4s.Github$GithubIOSyntaxEither.exec(Github.scala:62)
        at $line17.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$.<init>(<console>:31)

Response according to curl using the same token:

{
  "state": "success",
  "statuses": [
    {
      "url": "https://api.github.com/repos/Equiem/webhooks/statuses/595a30440c9473e7c4fbdb827127c6ab02995561",
      "id": 4349026842,
      "state": "success",
      "description": "Your tests passed on CircleCI!",
      "target_url": "https://circleci.com/gh/Equiem/webhooks/72?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link",
      "context": "ci/circleci",
      "created_at": "2017-11-27T08:10:20Z",
      "updated_at": "2017-11-27T08:10:20Z"
    }
  ],
  "sha": "595a30440c9473e7c4fbdb827127c6ab02995561",
  "total_count": 1,
  "repository": {
    "id": 90830371,
    "name": "webhooks",
    "full_name": "Equiem/webhooks",
    "owner": {
      "login": "Equiem",
      "id": 1195149,
      "avatar_url": "https://avatars1.githubusercontent.com/u/1195149?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/Equiem",
      "html_url": "https://github.com/Equiem",
      "followers_url": "https://api.github.com/users/Equiem/followers",
      "following_url": "https://api.github.com/users/Equiem/following{/other_user}",
      "gists_url": "https://api.github.com/users/Equiem/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/Equiem/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/Equiem/subscriptions",
      "organizations_url": "https://api.github.com/users/Equiem/orgs",
      "repos_url": "https://api.github.com/users/Equiem/repos",
      "events_url": "https://api.github.com/users/Equiem/events{/privacy}",
      "received_events_url": "https://api.github.com/users/Equiem/received_events",
      "type": "Organization",
      "site_admin": false
    },
    "private": true,
    "html_url": "https://github.com/Equiem/webhooks",
    "description": "Webhook injestion and stuff",
    "fork": false,
    "url": "https://api.github.com/repos/Equiem/webhooks",
    "forks_url": "https://api.github.com/repos/Equiem/webhooks/forks",
    "keys_url": "https://api.github.com/repos/Equiem/webhooks/keys{/key_id}",
    "collaborators_url": "https://api.github.com/repos/Equiem/webhooks/collaborators{/collaborator}",
    "teams_url": "https://api.github.com/repos/Equiem/webhooks/teams",
    "hooks_url": "https://api.github.com/repos/Equiem/webhooks/hooks",
    "issue_events_url": "https://api.github.com/repos/Equiem/webhooks/issues/events{/number}",
    "events_url": "https://api.github.com/repos/Equiem/webhooks/events",
    "assignees_url": "https://api.github.com/repos/Equiem/webhooks/assignees{/user}",
    "branches_url": "https://api.github.com/repos/Equiem/webhooks/branches{/branch}",
    "tags_url": "https://api.github.com/repos/Equiem/webhooks/tags",
    "blobs_url": "https://api.github.com/repos/Equiem/webhooks/git/blobs{/sha}",
    "git_tags_url": "https://api.github.com/repos/Equiem/webhooks/git/tags{/sha}",
    "git_refs_url": "https://api.github.com/repos/Equiem/webhooks/git/refs{/sha}",
    "trees_url": "https://api.github.com/repos/Equiem/webhooks/git/trees{/sha}",
    "statuses_url": "https://api.github.com/repos/Equiem/webhooks/statuses/{sha}",
    "languages_url": "https://api.github.com/repos/Equiem/webhooks/languages",
    "stargazers_url": "https://api.github.com/repos/Equiem/webhooks/stargazers",
    "contributors_url": "https://api.github.com/repos/Equiem/webhooks/contributors",
    "subscribers_url": "https://api.github.com/repos/Equiem/webhooks/subscribers",
    "subscription_url": "https://api.github.com/repos/Equiem/webhooks/subscription",
    "commits_url": "https://api.github.com/repos/Equiem/webhooks/commits{/sha}",
    "git_commits_url": "https://api.github.com/repos/Equiem/webhooks/git/commits{/sha}",
    "comments_url": "https://api.github.com/repos/Equiem/webhooks/comments{/number}",
    "issue_comment_url": "https://api.github.com/repos/Equiem/webhooks/issues/comments{/number}",
    "contents_url": "https://api.github.com/repos/Equiem/webhooks/contents/{+path}",
    "compare_url": "https://api.github.com/repos/Equiem/webhooks/compare/{base}...{head}",
    "merges_url": "https://api.github.com/repos/Equiem/webhooks/merges",
    "archive_url": "https://api.github.com/repos/Equiem/webhooks/{archive_format}{/ref}",
    "downloads_url": "https://api.github.com/repos/Equiem/webhooks/downloads",
    "issues_url": "https://api.github.com/repos/Equiem/webhooks/issues{/number}",
    "pulls_url": "https://api.github.com/repos/Equiem/webhooks/pulls{/number}",
    "milestones_url": "https://api.github.com/repos/Equiem/webhooks/milestones{/number}",
    "notifications_url": "https://api.github.com/repos/Equiem/webhooks/notifications{?since,all,participating}",
    "labels_url": "https://api.github.com/repos/Equiem/webhooks/labels{/name}",
    "releases_url": "https://api.github.com/repos/Equiem/webhooks/releases{/id}",
    "deployments_url": "https://api.github.com/repos/Equiem/webhooks/deployments"
  },
  "commit_url": "https://api.github.com/repos/Equiem/webhooks/commits/595a30440c9473e7c4fbdb827127c6ab02995561",
  "url": "https://api.github.com/repos/Equiem/webhooks/commits/595a30440c9473e7c4fbdb827127c6ab02995561/status"
}

Update documentation / microsite

We should take some time to update the docs and the microsite to reflect the changes that have been included in the library, maybe splitting the docs in several sections for the JVM and JS case uses.

Refactor algebras

We should have a criterium about the algebras and where we should place the new ops. Until now, we've created a new algebra per top level menu in GitHub API

In this case, we should:

  • Move Notifications into a new Algebra called Activity
  • Move Statuses ops into Repos

Integration tests create a bunch of gists

Not sure if this is a bug or not, but one of the integration tests seems to be creating a gist every time it's run... I ended up with 30~40 gists on my account without even realising it while working on #139 and #142 which was... annoying.

Target monad instances

Instances of cats.Id, scalaz.Task, etc should be isolated in different modules in order to be imported by users on demand.

Support Scala.js

It'd be awesome to support both Scala and Scala.js, since this library can be useful in both contexts. It shouldn't be too difficult since the library already uses an abstract HttpClient, which can have different implementations for Scala and Scala.js

Support pull request reviews

I've been using this library and really like it but I need access to pull request reviews, at least read-only access. How hard would it be to add this?

Missing test and docs

  • activity: Docs missing return value
  • auth: Missing Docs, Missing unit test
  • gist: Missing description integration test, Missing unit test
  • gitdata: Missing Docs, Missing integration test
  • issue: Doc missing return value in comments
  • pullrequest: Docs missing return value, Missing unit test
  • repo: Missing unit test
  • user: Missing Docs, Missing unit test

Possible duplicity

We have postAuth and postOAuth in httpClient.
The first receive a header built by the method in Auth API.
The second not receives a header but add one by himself.

Is possible delete postOuth and pass his header on the method?

Put and patch are coerced to post on the JVM

httpClient.patch[Issue](
  accessToken,
  s"repos/$owner/$repo/issues/$issue",
  headers,
  data = EditIssueRequest(state, title, body, milestone, labels, assignees).asJson.noSpaces)

will result in a POST on the JVM due to postData changing the verb to POST in scalaj.

A fix would imply changes to MockGithubApiServer where httpClient.patch are expected to be post (for the Issue and GitData APIs).

Changing API URL

Is there a way of changing the API URLs? I would like to use this library against an Enterprise GitHub and so I need to change the default URL.

I found that it is implicitly passed to individual constructors of the APIs in Interpreters.scala, but I have no idea if it can be changed to something else.

Just as a side note, I really like the design of the library in principle, but it is very hard to use for people that don't have experience with Cats. You should consider either improving the docs (I couldn't even get the current Getting Started to compile) or providing a higher level API on top, that does not leak the Monad abstractions and underlying libraries.

Integrate Coverall

In order to get a better summary of coverage reports, we should try to use Coverall.io

Patch should be optional on `PullRequestFile`

Why

I think that field may not be populated, esp for binary files. This causes breakage when you try to get files on a pull request.

Proof

Assuming you have jq installed:

$ curl https://api.github.com/repos/scala/scala/pulls/4877/files | jq '. | map(select(.patch == null))'

[
  {
    "sha": "7229603ae5b30ce0e0bd09863543b260085c8f2d",
    "filename": "src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png",
    "status": "removed",
    "additions": 0,
    "deletions": 0,
    "changes": 0,
    "blob_url": "https://github.com/scala/scala/blob/da3720e55b3d69cc31ab0f26e6cffafb18da360f/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png",
    "raw_url": "https://github.com/scala/scala/raw/da3720e55b3d69cc31ab0f26e6cffafb18da360f/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png",
    "contents_url": "https://api.github.com/repos/scala/scala/contents/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/arrow-down.png?ref=da3720e55b3d69cc31ab0f26e6cffafb18da360f"
  }, ...
]

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.