WordPress.org

Making WordPress.org

Changeset 3983


Ignore:
Timestamp:
09/07/16 06:02:21 (17 months ago)
Author:
dd32
Message:

GitHub Sync: Add support for the application/x-www-form-urlencoded webhook format and add documentation.

Location:
sites/trunk/api.wordpress.org/public_html/dotorg/github-sync
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/api.wordpress.org/public_html/dotorg/github-sync/feature-plugins.php

    r2698 r3983  
    11<?php 
    22/** 
    3  * A easy webhook to allow feature plugins to be sync'd to WordPress.org plugins SVN easier. 
     3 * This webhook is very basic, but handles syncing a select few featured plugins over to plugins.svn.wordpress.org during development. 
     4 * 
     5 * To have your *feature project* handled by this sync script: 
     6 * - Ensure you're listed on https://make.wordpress.org/core/features-as-plugins/ if you're not, ping in #meta 
     7 * - Ping in #meta to get your project added to the whitelist within this file 
     8 * - Add `https://api.wordpress.org/dotorg/github-sync/feature-plugins.php` as a `push` webhook on github with the secret we'll provide you. 
     9 * - Push to github master and watch https://plugins.trac.wordpress.org/log/$plugin_slug/ 
     10 * - Profit from all the Open Source points you're getting! 
    411 */ 
    512 
     
    815class GH2WORG { 
    916 
    10     private $whitelisted_repos = array( 
    11         // Github User/Repo => plugins.svn.wordpress.org/****/trunk/ 
    12         'dd32/feature-plugin-testing' => 'test-plugin-3', 
    13         'voldemortensen/menu-customizer' => 'menu-customizer', 
    14         'georgestephanis/two-factor' => 'two-factor', 
     17    private $whitelisted_repos = [ 
     18        // Github.com/{$user/repo-name} => plugins.svn.wordpress.org/{$slug}/trunk/ 
     19        'dd32/feature-plugin-testing'           => 'test-plugin-3', 
     20        'georgestephanis/two-factor'            => 'two-factor', 
    1521        'georgestephanis/application-passwords' => 'application-passwords', 
    16         'obenland/shiny-updates' => 'shiny-updates', 
    17         'pento/react' => 'react', 
    18     ); 
     22        'obenland/shiny-updates'                => 'shiny-updates', 
     23        'pento/react'                           => 'react', 
     24    ]; 
    1925 
    2026    function __construct() { 
    21         $this->populate_post_vars(); 
    22  
    23         if ( ! $this->verify_github_signature() ) { 
    24             die( 'Cheating, huh?' ); 
    25         } 
    26  
    27         $repo_name = $_POST['repository']['full_name']; 
    28         $repo_url  = $_POST['repository']['git_url']; 
    29  
    30         if ( ! $this->verify_valid_plugin( $repo_name ) ) { 
    31             die( 'Sorry, This Github repo is not configured for WordPress.org Plugins SVN Github Sync. Please contact us.' ); 
    32         } 
     27        $repo_name = $this->get_notified_repo(); 
    3328 
    3429        $svn_directory = $this->whitelisted_repos[ $repo_name ]; 
    3530 
    36         $this->process_github_to_svn( $repo_url, $svn_directory ); 
     31        if ( ! $repo_name || ! $svn_directory ) { 
     32            die( 'Sorry, This Github repo is not configured for WordPress.org Plugins SVN Github Sync. Please ping in #meta on Slack for assistance.' ); 
     33        } 
     34 
     35        $this->process_github_to_svn( $repo_name, $svn_directory ); 
    3736    } 
    3837 
    39     function populate_post_vars() { 
    40         if ( 'application/json' == $_SERVER['HTTP_CONTENT_TYPE'] ) { 
    41             $_POST = @json_decode( file_get_contents('php://input'), true ); 
    42         } else { 
    43             // Assuming Magic Quotes disabled like a good host. 
    44             $_POST = @json_decode( $_POST['payload'], true ); 
     38    /** 
     39     * Determines the Github Repo (user/repo) which Github is notifying us about. 
     40     * 
     41     * - Extracts the repo from both `application/json` and `application/x-www-form-urlencoded` webhook variants. 
     42     * - Verifies the signature of the request 
     43     * 
     44     * @return string|bool Github repo on success, false on failure. 
     45     */ 
     46    function get_notified_repo() { 
     47        $github_payload = file_get_contents( 'php://input' ); 
     48        $signature_of_payload = 'sha1=' . hash_hmac( 'sha1', $github_payload, FEATURE_PLUGIN_GH_SYNC_SECRET ); 
     49 
     50        if ( ! hash_equals( $signature_of_payload, $_SERVER['HTTP_X_HUB_SIGNATURE'] ) ) { 
     51            return false; 
    4552        } 
     53 
     54        /* 
     55         * Extract the payload from the `php://input` stream, although this is also present in 
     56         * $_POST, the Github signature is of this raw data, so we'll use that data. 
     57         */ 
     58        if ( 'application/x-www-form-urlencoded' === $_SERVER['HTTP_CONTENT_TYPE'] ) { 
     59            parse_str( $github_payload, $github_payload ); 
     60            $github_payload = $github_payload['payload']; 
     61        } 
     62 
     63        return json_decode( $github_payload, true )['repository']['full_name']; 
    4664    } 
    4765 
    48     function verify_github_signature() { 
    49         if ( empty( $_SERVER['HTTP_X_HUB_SIGNATURE'] ) ) 
    50             return false; 
     66    /** 
     67     * Triggers the shell script to migrate the Git commit to plugins.svn 
     68     * 
     69     * @param string $github_repo   The Github Repo which was modified (user/repo). 
     70     * @param string $svn_directory The plugins.svn directory/plugin (plugin-slug). 
     71     */ 
     72    function process_github_to_svn( $github_repo, $svn_directory ) { 
    5173 
    52         list( $algo, $hash ) = explode( '=', $_SERVER['HTTP_X_HUB_SIGNATURE'], 2 ); 
    53  
    54         // Todo? Doesn't handle standard $_POST, only application/json 
    55         $hmac = hash_hmac( $algo, file_get_contents('php://input' ), FEATURE_PLUGIN_GH_SYNC_SECRET ); 
    56  
    57         return $hash === $hmac; 
    58     } 
    59  
    60     function verify_valid_plugin( $repo ) { 
    61         return isset( $this->whitelisted_repos[ $repo ] ); 
    62     } 
    63  
    64     function process_github_to_svn( $github_url, $svn_directory ) { 
    65  
    66         putenv( 'PHP_SVN_USER=' . FEATURE_PLUGIN_GH_SYNC_USER ); 
     74        putenv( 'PHP_SVN_USER='     . FEATURE_PLUGIN_GH_SYNC_USER ); 
    6775        putenv( 'PHP_SVN_PASSWORD=' . FEATURE_PLUGIN_GH_SYNC_PASS ); 
    6876 
    69         echo shell_exec( __DIR__ . "/feature-plugins.sh $github_url $svn_directory 2>&1" ); 
     77        $github_repo   = escapeshellarg( $github_repo ); 
     78        $svn_directory = escapeshellarg( $svn_directory ); 
     79 
     80        echo shell_exec( __DIR__ . "/feature-plugins.sh $github_repo $svn_directory 2>&1" ); 
    7081 
    7182        putenv( 'PHP_SVN_USER' ); 
  • sites/trunk/api.wordpress.org/public_html/dotorg/github-sync/feature-plugins.sh

    r2295 r3983  
    11#!/bin/bash 
    22 
    3 GITHUB_URL=$1; 
     3GITHUB_REPO=$1; 
    44SVN_PLUGIN=$2; 
    55 
     
    1616 
    1717# Validate all Parameters are present 
    18 if [ ! $GITHUB_URL ] || [ ! $SVN_PLUGIN ] || [ ! $PHP_SVN_USER ] || [ ! $PHP_SVN_PASSWORD ]; then 
     18if [ ! $GITHUB_REPO ] || [ ! $SVN_PLUGIN ] || [ ! $PHP_SVN_USER ] || [ ! $PHP_SVN_PASSWORD ]; then 
    1919    echo "Invalid Input, missing parameter"; exit 1 
    2020fi 
    2121 
     22GITHUB_URL="git://github.com/$GITHUB_REPO.git" 
    2223SVN_URL="https://plugins.svn.wordpress.org/$SVN_PLUGIN/trunk/" 
    2324ASSETS_SVN_URL="https://plugins.svn.wordpress.org/$SVN_PLUGIN/assets/" 
Note: See TracChangeset for help on using the changeset viewer.