Skip to content

Commit

Permalink
Implement the action (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 committed Oct 6, 2021
1 parent 3cac1d7 commit be2ef5b
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2021, Google LLC

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
This is a small utility action that clones a repository, using a ref linked from
a pull request if possible.

For example:

```yaml
jobs:
sass-spec:
name: Language Tests
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
dart_channel: [stable, dev]
async_label: [synchronous]
async_args: ['']
include:
- dart_channel: stable
async_label: asynchronous
async_args: '--cmd-args --async'

steps:
- uses: actions/checkout@v2
- uses: dart-lang/setup-dart@v1
with: {sdk: stable}
- uses: actions/setup-node@v2
with: {node-version: 16}
- run: dart pub get

- name: Check out sass-spec
uses: sass/clone-linked-repo@v1
args: {repo: sass/sass-spec}
- run: npm install
working-directory: sass-spec
- name: Run specs
run: npm run sass-spec -- --dart .. $extra_args
working-directory: sass-spec
env: {extra_args: "${{ matrix.async_args }}"}
```

By default, this will clone `sass-spec`'s `main` branch into the `sass-spec`
path. But if a PR contains the text "sass/sass-spec#123" and there's a pull
request with ID 123, it will clone `pull/123/head` instead.

This action is meant primarily for Sass repositories. Other repositories are
welcome to use it, but please be aware that support will be a very low
priority.

## Details

* This will recognize both short references (`sass/sass-spec#123`) and full URLs
(`https://github.com/sass/sass-spec/pulls/123`).

* This will ignore issue references.

* If the PR message contains multiple references to a PR from the same
repository, this will use the first one.
68 changes: 68 additions & 0 deletions action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Cloned Linked Repo
description: Clone a repo at a version linked from a PR description.

inputs:
repo:
description: >
The slug (e.g. "sass/sass") of the repository whose PR links this action
should look for.
required: true
token:
description: >
The GitHub token used to access the pull request's message.
default: ${{ github.token }}
default-ref:
description: >
The default branch to check out when this isn't a PR or doesn't link to a
PR. Note that if the current branch or PR base is of the form "feature.*",
this will always use the same branch name as the default.
default: main
ssh-key:
description: Passed directly to actions/checkout.
ssh-known-hosts:
description: Passed directly to actions/checkout.
ssh-strict:
description: Passed directly to actions/checkout.
persist-credentials:
description: Passed directly to actions/checkout.
path:
description: Passed directly to actions/checkout.
clean:
description: Passed directly to actions/checkout.
fetch-depth:
description: Passed directly to actions/checkout.
lfs:
description: Passed directly to actions/checkout.
submodules:
description: Passed directly to actions/checkout.

runs:
using: composite
steps:

- run: "bash $GITHUB_ACTION_PATH/find-ref.sh"
id: find-ref
shell: bash
env:
PR_BRANCH: ${{ github.base_ref }}
CURRENT_REF: ${{ github.ref }}
PR_BODY: ${{ github.event.pull_request.body }}
# Inputs must be repeated due to actions/runner#665
REPO: ${{ inputs.repo }}
TOKEN: ${{ inputs.token }}
DEFAULT_REF: ${{ inputs.default-ref }}

- uses: actions/checkout@v2
with:
repository: ${{ inputs.repo }}
ref: ${{ steps.find-ref.outputs.ref }}
token: ${{ inputs.token }}
ssh-key: ${{ inputs.ssh-key }}
ssh-known-hosts: ${{ inputs.ssh-known-hosts }}
ssh-strict: ${{ inputs.ssh-strict }}
persist-credentials: ${{ inputs.persist-credentials }}
path: ${{ inputs.path }}
clean: ${{ inputs.clean }}
fetch-depth: ${{ inputs.fetch-depth }}
lfs: ${{ inputs.lfs }}
submodules: ${{ inputs.submodules }}
54 changes: 54 additions & 0 deletions find-ref.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash -e
# Copyright 2021 Google Inc. Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.

# Echoes the sass/sass Git ref that should be checked out for the current GitHub
# Actions run. If we're running specs for a pull request which refers to a
# sass/sass pull request, we'll run against the latter rather than sass/sass
# main.
if [ -z "$PR_BRANCH" ]; then
# Remove the "refs/heads/" prefix
current_branch="${CURRENT_REF/refs\/heads\//}"
else
current_branch="$PR_BRANCH"
fi

if [[ "$current_branch" == feature.* ]]; then
default="$current_branch"
else
default="$DEFAULT_REF"
fi

# We don't have a PR_BRANCH so we are not in a pull request, so there's no
# linked PR to find.
if [ -z "$PR_BRANCH" ]; then
echo "::set-output name=ref::$default"
exit 0
fi

echo "::group::Pull request body"
echo "$PR_BODY"
echo "::endgroup::"

echo "::group::Finding pull request reference"
for link in "$(echo "$PR_BODY" | grep -Eo "${REPO}(#|/pull/)[0-9]+")"; do
if [[ "$link" = *#* ]]; then
number="${link#*#}"
else
number="${link#*/pull/}"
fi

if curl --fail --silent --head --header "Authorization: token $TOKEN" \
"https://api.github.com/repos/$REPO/pulls/${number}" > /dev/null; then
echo "Linked to pull request $number"
echo "::set-output name=ref::refs/pull/$number/head"
exit 0
else
echo "$link isn't a pull request."
fi
done

echo "No linked pull request, using default ref $default"
echo "::set-output name=ref::$default"
echo "::endgroup::"

0 comments on commit be2ef5b

Please sign in to comment.