How we built the GitHub globe

The GitHub homepage features a very nice rotating 3D globe, augmented with realtime data shooting around. Here’s how they built it:

At the most fundamental level, the globe runs in a WebGL context powered by three.js. We feed it data of recent pull requests that have been created and merged around the world through a JSON file. The scene is made up of five layers: a halo, a globe, the Earth’s regions, blue spikes for open pull requests, and pink arcs for merged pull requests. We don’t use any textures: we point four lights at a sphere, use about 12,000 five-sided circles to render the Earth’s regions, and draw a halo with a simple custom shader on the backside of a sphere.

How we built the GitHub globe →

Customizing GitHub Gist Embeds

When embedding a GitHub Gist using a script tag, its contents gets injected into your page’s DOM. As the injected wrapper node has a .gist class, it’s perfectly possible to customize the appearance on your own site. Will Boyd walks us through it.

Will also created a repository with several pre-built themes. Simply add one of the CSS files to your page, and you’re good to go.

@import url('https://cdn.rawgit.com/lonekorean/gist-syntax-themes/848d6580/stylesheets/monokai.css');

Customizing GitHub Gists →
Gist Syntax Themes →

Automatically update your GitHub readme through GitHub Actions

Pawel Grzybek has set up a workflow that uses GitHub Actions’ Scheduled Events to automatically update his profile README.md. It runs every 6 hours and pulls in his RSS feed to populate the README.md

import fs from "fs";
import fetch from "node-fetch";
import parser from "xml2json";

const FEED_URL = "https://pawelgrzybek.com/feed.xml";
const TAG_OPEN = `<!-- FEED-START -->`;
const TAG_CLOSE = `<!-- FEED-END -->`;

const fetchArticles = async () => {
  const articles = await fetch(FEED_URL);
  const articlesText = await articles.text();
  const articlesJSON = parser.toJson(articlesText);
  const newC = JSON.parse(articlesJSON).rss.channel.item.slice(0, 5);

  return newC.map(({ title, link }) => `- [${title}](${link})`).join("\n");
};

async function main() {
  const readme = fs.readFileSync("./README.md", "utf8");
  const indexBefore = readme.indexOf(TAG_OPEN) + TAG_OPEN.length;
  const indexAfter = readme.indexOf(TAG_CLOSE);
  const readmeContentChunkBreakBefore = readme.substring(0, indexBefore);
  const readmeContentChunkBreakAfter = readme.substring(indexAfter);

  const posts = await fetchArticles();

  const readmeNew = `
${readmeContentChunkBreakBefore}
${posts}
${readmeContentChunkBreakAfter}
`;

  fs.writeFileSync("./README.md", readmeNew.trim());
}

try {
  main();
} catch (error) {
  console.error(error);
}

Fetch most recent posts to your GitHub profile page using GitHub workflow and Node.js →

💡 People have been doing lots of nice stuff with their README’s. There’s a curated list to be found at matiassingers/awesome-readme (and plenty of others if you search for them)

Run your GitHub Actions locally with act

When you run act it reads in your GitHub Actions from .github/workflows/ and determines the set of actions that need to be run. It uses the Docker API to either pull or build the necessary images, as defined in your workflow files and finally determines the execution path based on the dependencies that were defined. Once it has the execution path, it then uses the Docker API to run containers for each action based on the images prepared earlier. The environment variables and filesystem are all configured to match what GitHub provides.

Installation per brew (if you’re on Mac):

brew install nektos/tap/act

Once installed, run act and you’re good to go …

# List the actions
act -l

# Run the default (`push`) event:
act

# Run a specific event:
act pull_request

# Run a specific job:
act -j test

# Run in dry-run mode:
act -n

# Enable verbose-logging (can be used with any of the above commands)
act -v

act

Webmentions on a static site with GitHub Actions

Sebastian his website supports Webmentions. To show these on his website he used a tad of JS to display them underneath each page. Not being 100% happy with that flow, he sought a better way to implement these …

After some tinkering, I came up with an alternative: a cron-based GitHub Action that queries webmention.io for new webmentions. The Action then commits them to my site’s repository, so I can access the data with my static site generator, Hugo.

Clever!

Webmentions on a static site with GitHub Actions →

🔥 Those “GitHub Cron Jobs” once again prove to be really powerful. You can even use them to trigger a Netlify build on a daily basis.

RSS Feeds for GitHub Project Releases and User Activity

As an extra to RSS feed for youtube channels and GitHub projects, Pawel notes that it’s also possible to get a feed for the releases published in GitHub Projects.

GitHub gives us RSS feeds for project releases and tags. Thats my preferred way of finding out about my followed projects fixed bugs and new features.

https://github.com/{{username}}/{{repository}}/releases.atom
https://github.com/{{username}}/{{repository}}/tags.atom

Ah, that I didn’t know!

I noticed that this also works for user activity feeds btw. Just like you can append .keys to any GitHub User Profile Page to see their public keys, you can append .atom to get their (public) activity feed.

https://github.com/{{username}}.atom

Here’s my activity feed for example: https://github.com/bramus.atom

RSS feed for youtube channels and GitHub projects →

Easily Build and push Docker images with the `build-push-action` GitHub Action

The Docker folks have released their first GitHub Action build-push-action which builds and pushes Docker images and will log in to a Docker registry if required.

Building and pushing an image becomes really easy:

uses: docker/[email protected]
with:
  username: ${{ secrets.DOCKER_USERNAME }}
  password: ${{ secrets.DOCKER_PASSWORD }}
  repository: myorg/myrepository
  tags: latest

Amongst other options you can also define a registry, which defaults to the Docker Hub.

Build and push Docker images GitHub Action →

Draft your next release notes as pull requests are merged into master with Release Drafter

Now this looks handy: a GitHub action that builds release notes for you:

As pull requests are merged, a draft release is kept up-to-date listing the changes, ready to publish when you’re ready

You configure the release notes contents using a .github/release-drafter.yml file in your repo:

template: |
  ## What’s Changed

  $CHANGES

More advanced templates are also possible:

name-template: 'v$NEXT_PATCH_VERSION 🌈'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: '🚀 Features'
    labels:
      - 'feature'
      - 'enhancement'
  - title: '🐛 Bug Fixes'
    labels:
      - 'fix'
      - 'bugfix'
      - 'bug'
  - title: '🧰 Maintenance'
    label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  ## Changes

  $CHANGES

The template above yields this kind of result:

Nice!

Release Drafter →

GitHub acquires npm

It was suggested that Microsoft/GitHub should have bought npm back in the day, instead of launching their own registry. Today is the day they’ve actually done it:

We at GitHub are honored to be part of the next chapter of npm’s story and to help npm continue to scale to meet the needs of the fast-growing JavaScript community.

For the millions of developers who use the public npm registry every day, npm will always be available and always be free. Looking further ahead, we’ll integrate GitHub and npm to improve the security of the open source software supply chain, and enable you to trace a change from a GitHub pull request to the npm package version that fixed it.

npm is joining GitHub →

Getting started with GitHub Actions and Laravel (~PHP)

Ruben Van Assche from Spatie:

When GitHub released its new product: GitHub Actions a whole new world opened for developers. Let’s dive right in and see what it brings for the Laravel community.

In How to set up PHP for use in a GitHub Action I’ve layed out how to use shivammathur/[email protected] in GitHub Actions. This post goes very nicely along with it. Recommended read, even if you don’t write Laravel (like me).

I especially like the part where an extra MySQL service is spun up from within the workflow, and then used in the tests.

// ...

jobs:
    tests:
        // ...

        services:
            mysql:
                image: mysql:5.7
                env:
                    MYSQL_ALLOW_EMPTY_PASSWORD: yes
                    MYSQL_DATABASE: our-awesome-tested-app
                ports:
                    - 3306
                options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
                
        // ...

Getting started with GitHub Actions and Laravel →