diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml new file mode 100644 index 00000000000000..d4c364e2bb2f52 --- /dev/null +++ b/.github/workflows/auto-start-ci.yml @@ -0,0 +1,65 @@ +--- +name: Auto Start CI + +on: + push: + schedule: + # `schedule` event is used instead of `pull_request` because when a + # `pull_requesst` event is triggered on a PR from a fork, GITHUB_TOKEN will + # be read-only, and the Action won't have access to any other repository + # secrets, which it needs to access Jenkins API. Runs every five minutes + # (fastest the scheduler can run). Five minutes is optimistic, it can take + # longer to run. + - cron: "*/5 * * * *" + +jobs: + commitQueue: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + + # Install dependencies + - name: Install jq + run: sudo apt-get install jq -y + - name: Install Node.js + uses: actions/setup-node@v2-beta + with: + node-version: '12' + - name: Install node-core-utils + run: npm install -g node-core-utils + + - name: Set variables + run: | + echo "::set-env name=REPOSITORY::$(echo ${{ github.repository }} | cut -d/ -f2)" + echo "::set-env name=OWNER::${{ github.repository_owner }}" + + # Get Pull Requests + - name: Get Pull Requests + uses: octokit/graphql-action@v2.x + id: get_prs_for_ci + with: + query: | + query prs($owner:String!, $repo:String!) { + repository(owner:$owner, name:$repo) { + pullRequests(labels: ["request-ci"], states: OPEN, last: 100) { + nodes { + number + } + } + } + } + owner: ${{ env.OWNER }} + repo: ${{ env.REPOSITORY }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup node-core-utils + run: | + ncu-config set username ${{ secrets.JENKINS_USER }} + ncu-config set token none + ncu-config set jenkins_token ${{ secrets.JENKINS_TOKEN }} + ncu-config set owner ${{ env.OWNER }} + ncu-config set repo ${{ env.REPOSITORY }} + + - name: Start CI + run: ./tools/start-ci.sh ${{ secrets.GITHUB_TOKEN }} ${{ env.OWNER }} ${{ env.REPOSITORY }} $(echo '${{ steps.get_prs_for_ci.outputs.data }}' | jq '.repository.pullRequests.nodes | map(.number) | .[]') diff --git a/tools/actions/start-ci.sh b/tools/actions/start-ci.sh new file mode 100755 index 00000000000000..528c3544b17fa9 --- /dev/null +++ b/tools/actions/start-ci.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -xe + +GITHUB_TOKEN=$1 +OWNER=$2 +REPOSITORY=$3 +API_URL=https://api.github.com +REQUEST_CI_LABEL='request-ci' +REQUEST_CI_FAILED_LABEL='request-ci-failed' +shift 3 + +function issueUrl() { + echo "$API_URL/repos/${OWNER}/${REPOSITORY}/issues/${1}" +} + +function labelsUrl() { + echo "$(issueUrl "${1}")/labels" +} + +function commentsUrl() { + echo "$(issueUrl "${1}")/comments" +} + +for pr in "$@"; do + curl -sL --request DELETE \ + --url "$(labelsUrl "$pr")"/"$REQUEST_CI_LABEL" \ + --header "authorization: Bearer ${GITHUB_TOKEN}" \ + --header 'content-type: application/json' + + ci_started=yes + rm -f output; + ncu-ci run "$pr" >output 2>&1 || ci_started=no + + if [ "$ci_started" == "no" ]; then + # Do we need to reset? + curl -sL --request PUT \ + --url "$(labelsUrl "$pr")" \ + --header "authorization: Bearer ${GITHUB_TOKEN}" \ + --header 'content-type: application/json' \ + --data '{"labels": ["'"${REQUEST_CI_FAILED_LABEL}"'"]}' + + jq -n --arg content "
Couldn't start CI
$(cat output)
" '{body: $content}' > output.json + + curl -sL --request POST \ + --url "$(commentsUrl "$pr")" \ + --header "authorization: Bearer ${GITHUB_TOKEN}" \ + --header 'content-type: application/json' \ + --data @output.json + + rm output.json; + fi +done;