ianwremmel
9/21/2017 - 1:34 AM

Work in Progress for wiring up the bare-minimum github/ci flow

Work in Progress for wiring up the bare-minimum github/ci flow

#!/usr/bin/env bash

# TODO do not push package.json until circle ci is following the repo
# TODO add local template for package.json
# TODO every curl needs better success checking
# TODO non-interactive mode 
# TODO create CONTRIBUTE.md
# TODO create github issue template
# TODO create editorconfig
# TODO create eslintrc.yml
# TODO create gitignore
# TODO consider creating circle.yml
# - fail if ~/.netrc not configured
# - skip branch protection
# External dependencies:
# - curl
# - read
# - jq
# TODO accept vars from command line
# - project name
# - project description
# - skip readme
# - skip package.json
# - skip contribute
# - skip issue template
# - public instead of private

set -e

if [ "$(curl -ns https://circleci.com/api/v1.1/me -s -o /dev/null -w "%{http_code}")" == "401" ]; then
    if grep -q 'machine circleci' ~/.netrc; then
        echo '~/.netrc appears to have invalid config for Circle CI'
        exit 1
    fi

    echo 'Your ~/.netrc does not appear to be configured for Circle CI'
    read -srp 'Please enter your Circle CI API Token: ' CIRCLE_TOKEN
    echo
    echo 'machine circleci.com' >> ~/.netrc
    echo "  login ${CIRCLE_TOKEN}" >> ~/.netrc
fi

if [ "$(curl -ns https://api.github.com/user -s -o /dev/null -w "%{http_code}")" == "401" ]; then
    if grep -q 'machine api.github.com' ~/.netrc; then
        echo '~/.netrc appears to have invalid config for GitHub'
        exit 1
    fi

    echo 'Your ~/.netrc does not appear to be configured for GitHub'
    read -rp 'Please enter your GitHub Username: ' GITHUB_USERNAME
    read -srp 'Please enter your GitHub Password: ' GITHUB_PASSWORD
    echo
    {
        echo 'machine api.github.com'
        echo "  login ${GITHUB_USERNAME}"
        echo "  password ${GITHUB_PASSWORD}" 
    } >> ~/.netrc
fi

if [ "$#" -gt "0" ]; then
    DIR="$1"    
    mkdir "${DIR}"
else
    DIR='.'
fi

cd "${DIR}"
if [ -z "${PROJECT_NAME}" ]; then
    PROJECT_NAME=$(basename "$(pwd)")
fi

echo "Determined project name to be ${PROJECT_NAME}"
read -rp "Press any key if that name is correct... " -n1 -s
echo 

if [ -z "${CIRCLECI_USERNAME}" ]; then
    CIRCLECI_USERNAME=$(curl -ns https://circleci.com/api/v1.1/me  | jq .login -r)
fi  

if [ -z "${GITHUB_USERNAME}" ] || [ -z "${GITHUB_DISPLAY_NAME}" ]; then
    GH_USER_INFO=$(curl -ns https://api.github.com/user)
    GITHUB_USERNAME=$(echo "${GH_USER_INFO}" | jq .login -r)
    GITHUB_DISPLAY_NAME=$(echo "${GH_USER_INFO}" | jq .name -r)
fi

if [ ! -d '.git' ]; then
    echo 'Creating local git repository'
    git init

    echo 'Creating initial, empty commit'
    git commit -m 'root' --allow-empty
fi

if [ ! -f "package.json" ]; then
    echo 'Creating default package.json'
    npm init -y
    
    git add package.json
    git commit -m 'chore(package): Create initial package.json'
fi

if [ ! -f "README.md" ]; then 
    echo 'Creating standard readme'
    echo \
"# ${PROJECT_NAME}

[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)

> Short Description

## Install

## Usage

## Maintainers

[${GITHUB_DISPLAY_NAME}](https://github.com/${GITHUB_USERNAME})

## Contribute

See [CONTRIBUTE](CONTRIBUTE.md)

## License

© [License Type](LICENSE) " > README.md

    read -rp "Please edit README.md and then press any key to continue... " -n1 -s
    
    git add README.md
    git commit -m 'docs(readme): Create initial README'
fi

echo 'Creating private GitHub repository'
# note: apparently aliases don't work in shell scripts, so we have to use `hub` 
# instead of `git`
hub create --private

git push -u origin master:master

echo 'Following project on CircleCI'
RESPONSE_BODY=$(curl -ns -X POST "https://circleci.com/api/v1.1/project/github/${CIRCLECI_USERNAME}/${PROJECT_NAME}/follow")
echo $RESPONSE_BODY
FOLLOWED=$(echo "${RESPONSE_BODY}" | jq .followed)
FOLLOWING=$(echo "${RESPONSE_BODY}" | jq .following)
if [ "${FOLLOWED}" != "true" ] && [ "${FOLLOWING}" != "true" ]; then
  echo 'Failed to follow project'
  exit 1
fi

echo 'Enable autocancel builds, build fork PRs, and disabling secrets on fork PRs'
curl "https://circleci.com/api/v1.1/project/github/${CIRCLECI_USERNAME}/${PROJECT_NAME}/settings" \
    -ns \
    -X PUT \
    --data '{"feature_flags":{"autocancel-builds":true,"build-fork-prs":true,"forks-receive-secret-env-vars":false}}' 

echo 

# TODO skip this block if checks are enabled
echo "Unfortunately, the next step doesn't seem to be possible from the GitHub API"
echo "Please check the boxes for"
echo '"Protect this branch"'
echo '"Require status checks to pass before merging"'
echo "Please manually enable branch protection and required status checks. You "
echo "don't need to require specific checks, just enable the feature. After you've "
echo "enabled the features, return to this window."
read -rp "Press any key to open github.com " -n1 -s
echo
open "https://github.com/${GITHUB_USERNAME}/${PROJECT_NAME}/settings/branches/master"
read -rp "Press any key to continue after enable branch protection " -n1 -s
echo

echo 'Require Circle CI to pass before merging to master'
curl "https://api.github.com/repos/${GITHUB_USERNAME}/${PROJECT_NAME}/branches/master/protection/required_status_checks/contexts" \
    -ns \
    --data '["ci/circleci"]'

echo 'Require branch to be up to date befor merging'
curl "https://api.github.com/repos/${GITHUB_USERNAME}/${PROJECT_NAME}/branches/master/protection/required_status_checks" \
    -ns \
    --data '{"strict": true, "contexts": ["ci/circleci"]' \
    -X PATCH

echo 'Protect master branch from admins'
curl "https://api.github.com/repos/${GITHUB_USERNAME}/${PROJECT_NAME}/branches/master/protection/enforce_admins" \
    -ns \
    -X POST 


# function request() {
#     URL=$1
#     METHOD=$2
#     EXPECTED_STATUS=$3

#     STATUS=$(curl "${URL}" -X "${METHOD}" -o /dev/null -w "%{http_code}"))
# }



# if [ "$(curl -ns https://circleci.com/api/v1.1/me -s -o /dev/null -w "%{http_code}")" == "401" ]; then