DEV Community

loading...
Cover image for More Eyes, Plz! Hackathon entry + update

More Eyes, Plz! Hackathon entry + update

jeremyong profile image Jeremy Ong ・5 min read

Here are the updates made since the original progress post:

  • added support for bot commands, starting with the [meep close] command
  • the site now fetches labels created dynamically for new meep requests
  • the site is now responsive on mobile/tablet
  • meeps are only filed at most once (in the event the same commit is pushed to multiple branches)

Thanks to everyone who took it for a spin and/or submitted feedback!

My Workflow

Getting started with a new programming language or framework? Trying to learn a new paradigm like functional programming? Perhaps you're getting started with a new discipline, like compiler engineering or graphics programming? Normally, we'd learn by authoring code in a "sandbox" and see what works while following along a book or tutorial. But what if you would like some pointers or feedback from someone more experienced? Stackoverflow could work, but the site encourages questions with a high degree of specificity. You can't just ask for holistic feedback for code.

More Eyes, Plz! is a service powered by Github actions to easily crowdsource commits made to any repository. To get started simply install the meep scanner action to the repo you'd like to get feedback on, or copy the following snippet to .github/workflows/meep.yml:

name: meep_scanner
on: [push]

jobs:
  meep_scan:
    runs-on: ubuntu-latest
    steps:
    - uses: moreeyesplz/meep_scanner@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}

After the action is installed, simply write [meep] or [MEEP] somewhere in the commit notes. Here's an example commit message:

commitmessage

Shortly after, the bot will post a comment that looks like the following to the commit itself:

commitcomment

The commit link will also be indexed on the website and show up as follows for others to see:

meep

Afterwards, expect to get some feedback!

feedback

When you're satisfied with the feedback, simply write [meep close] in the commit thread to unlist the meep from the database.

Submission Category:

Maintainer Must Haves

Yaml File or Link to Code

Only one repository is relevant for actually integrating with the More Eyes, Plz! service:

GitHub logo moreeyesplz / meep_scanner

Integrate this action into your repository to start crowdsourcing feedback for your commits!

MEEP Scanner

The MEEP Scanner is a lightweight action that integrates with the More Eyes, Plz! service. When installed in a repository, the scanner scans commit messages for the [MEEP] or [meep] string. When present, the commit becomes indexed in the MEEP database for others in the community to discover.

Note that this action only works on repositories that are public at this time. Without public visibility, outside members of the community will not be able to view your commits to provide feedback.

Usage

For each repository you wish to potentially request feedback on, please performing the following steps:

1. Add topics to your repository

Topics added help others discover your requests more easily through filters. To do this, hit the settings wheel at the top right of your repository's home page. Then, add topics that pertain to your code. This could be the programming language, a framework or library…

The action that responds to the scan to write the commit comment and also file an issue to the meeps tracker is here:

GitHub logo moreeyesplz / meeper

Internal action which accepts meeps scanned by the meep_scanner

meeper

Internal action which accepts meeps scanned by the meep_scanner. This action is dispatched only via an API call to invoke the workflow_dispatch event.




Another action is used to respond to workflow_dispatch events needed to power bot commands such as [meep close]:

GitHub logo moreeyesplz / themeepbot

Webhook responder for themeepbot

themeepbot

Webhook responder for themeepbot




Finally, the website itself is hosted via github pages and is itself open source as well:

GitHub logo moreeyesplz / moreeyesplz.github.io

Public-facing website aggregating and displaying meeps

This project was bootstrapped with Create React App.

Available Scripts

In the project directory, you can run:

yarn start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

yarn test

Launches the test runner in the interactive watch mode.
See the section about running tests for more information.

yarn build

Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

See the section about deployment for more information.

yarn eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration…

Even the deployment of the site (created via create-react-app) is automated using a workflow which may be useful to others. The code used is pasted below:

name: deploy
on: ['workflow_dispatch']

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: checkout
      uses: actions/checkout@v2
      with:
        ref: master
        fetch-depth: 0
        clean: false
    - name: cache dependencies
      id: cache
      uses: actions/cache@v2
      with:
        path: node_modules
        key: ${{ runner.os }}-${{ hashFiles('package.json') }}
    - name: install dependencies
      if: steps.cache.outputs.cache-hit != 'true'
      run: npm install
    - name: build site
      run: |
        npm run build
        git config --local user.email "bot@moreeyesplz.com"
        git config --local user.name "themeepbot"
        git checkout site
        cp -r build/* ./
        rm -rf build
        git add .
        git commit -m'Automated build'
        git push origin site

Feel free to adapt this for your needs! The only thing you would probably want to change is the identifying user.email and user.name local git config (it needs to push to the site branch).

Additional Resources / Info

This project was done in collaboration with @duchesstoffee (my wife). She did the frontend, responsible for querying the meeps database (hosted using the issue tracker of this meta repo), fetch labels, and enabling tag-based searching. The frontend is built as a single page application, using the fetch API and OAuth credentials to pull data from Github.

Here is a list of dependencies used for the frontend:

The backend is largely driven via actions and Github itself, with no database or dedicated servers. However, a few Google Cloud functions are used simply to proxy information in a secure manner in cases where we could not ship a developer secret (with write credentials to the meeps repo) to the client. A Google Cloud function is also used to handle the oauth redirect. Here's the code for the Oauth handling for example, which runs on vanilla nodejs with no dependencies:

const https = require('https');

const HOST = process.env.HOST;

exports.auth = (req, res) => {
    if (!req.query.code) {
        return res.sendStatus(401);
    }

    https.request({
        host: 'github.com',
        path: `/login/oauth/access_token?code=${req.query.code}&client_id=${process.env.OAUTH_ID}&client_secret=${process.env.OAUTH_SECRET}`,
        method: 'POST',
        headers: {
            Accept: 'application/json',
        }
    }, (login_res) => {
        login_res.setEncoding('utf8');
        const chunks = [];

        login_res.on('data', chunks.push);
        login_res.on('error', console.error);

        login_res.on('end', () => {
            const payload = JSON.parse(chunks.join(''));
            if (payload.error) {
                res.status(401).redirect(`${HOST}?login_failed`);
            } else {
                res.status(200).redirect(`${HOST}?access_token=${payload.access_token}&scope=${payload.scope}`);
            }
        });
    }).end();
};

Here's the code for the Google Cloud function which handles the Github Webhook and forwards it as a workflow dispatch event to themeepbot bot workflow:

const https = require('https');

exports.webhook = (req, res) => {
    // Validate github user-agent
    if (!req.headers['user-agent'].startsWith('GitHub-Hookshot')) {
        return res.sendStatus(404);
    }

    const event = req.headers['x-github-event'];
    if (!event) {
        console.error('Missing event from request payload');
        return res.sendStatus(404);
    }

    const body = JSON.stringify({
        ref: 'master',
        inputs: {
            payload: Buffer.from(JSON.stringify(req.body)).toString('base64'),
            event,
        }
    });
    const request = https.request({
        host: 'api.github.com',
        path: `/repos/moreeyesplz/themeepbot/actions/workflows/bot.yml/dispatches`,
        method: 'POST',
        headers: {
            Accept: 'application/vnd.github.v3+json',
            Authorization: `token ${process.env.GITHUB_TOKEN}`,
            'User-Agent': 'moreeyesplz',
            'Content-Type': 'application/json',
            'Content-Length': body.length,
        }
    }, (response) => {
        response.setEncoding('utf8');
        const chunks = [];
        response.on('data', (chunk) => chunks.push(chunk));
        response.on('end', () => {
            if (response.statusCode !== 204) {
                console.error(`Workflow not dispatched: ${chunks.join('')}`);
            }
            res.sendStatus(response.statusCode);
        })
    });
    request.write(body);
    request.end();
}

The main "implementation detail" here is that workflow event payloads have far more keys and nested objects than what the workflow_dispatch can receive as inputs (limit is 10). As a workaround, this event proxy simply base64 encodes the entire payload and forwards it as a single event for the downstream action to parse later. Thus, the "heavy lifting" that needs to interact with the Github APIs can be done in action-based workflows.

All the actions and workflow code are very light on dependencies, using only the actions toolkit.

Discussion

pic
Editor guide
Collapse
aliahsan07 profile image
Ali Ahsan

this is good stuff

Collapse
jeremyong profile image
Jeremy Ong Author

Thanks a ton :)

Collapse
developerkaren profile image
Karen Efereyan

Congrats Jeremy. Though I have not the slightest idea of anything written here

Collapse
jeremyong profile image
Jeremy Ong Author

If you have any specific questions I'm happy to help answer them or point you to resources where you can learn more!