Skip to content

Commit

Permalink
feat!: Initial Add (#1)
Browse files Browse the repository at this point in the history
* Adding Action, support files and tests

* Test fix on pndurette/gh-actions-auto-docs

* Fix root action path

* GitHub Action Auto-Docs

* Move _config.yml out of the root so the local run doesn't try to copy it onto itself

* Use real latest releast of gh-actions-auto-docs

* Add missing bats tests

* Try theme: none in _config.yml

* Try theme: null in _config.yml

* Test README.md

* GitHub Action Auto-Docs

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* Test README.md

* GitHub Action Auto-Docs

* Test README.md

* GitHub Action Auto-Docs

* Update terminology, add how it works

* typo, add badge

* Simplified README.md

* Simplified README.md

* Simplified README.md

* Simplified README.md

* Format as list

* GitHub Action Auto-Docs

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
pndurette and github-actions[bot] authored Mar 5, 2023
1 parent 2026986 commit 75300a5
Show file tree
Hide file tree
Showing 9 changed files with 613 additions and 1 deletion.
19 changes: 19 additions & 0 deletions .github/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
plugins:
# Adds 'redirect_to' attribute to front-matter (whitelisted by GitHub Pages)
# https://github.com/jekyll/jekyll-redirect-from
- "jekyll-redirect-from"

# Override GitHub Pages' default
# "Primer" theme to no theme
# (prevents generation of assets)
theme: null

collections:
redirects:
output: true
permalink: /:name

exclude:
- README.md
- LICENSE
- .*
22 changes: 22 additions & 0 deletions .github/workflows/action-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Generate Action Docs

on: [pull_request]

jobs:
docs:
name: Docs
runs-on: ubuntu-latest

permissions:
# Required to push changes!
contents: write

steps:
- uses: actions/checkout@v3
with:
# Required to push changes!
ref: ${{ github.event.pull_request.head.ref }}

- uses: pndurette/gh-actions-auto-docs@v1
with:
include_outputs: false
47 changes: 47 additions & 0 deletions .github/workflows/test-reusable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Reusable Workflow for a Bats test of the Action

on:
workflow_call:
inputs:
# Pre-Action commands
pre-run:
required: false
type: string

# Explicit Action inputs
urls_config:
required: true
type: string
default_redirect:
required: true
type: string

# Post-Action commands
post-run:
required: true
type: string

jobs:
bats-test:
name: Bats Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install Bats
run: npm install -g [email protected]
- name: Pre-Run
run: |
${{ inputs.pre-run }}
- name: Run Action
uses: ./
with:
urls_config: ${{ inputs.urls_config }}
default_redirect: ${{ inputs.default_redirect }}
- name: Post-Run
run: |
${{ inputs.post-run }}
50 changes: 50 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Tests

on:
pull_request:
branches: ["main"]

permissions:
contents: read
# Required for actions/jekyll-build-pages:
id-token: write
pages: write

jobs:
test-generation:
name: Generate Redirects
uses: ./.github/workflows/test-reusable.yml
with:
pre-run: |
# Create a test urls config file
cat <<- EOF > urls_tests.yml
---
test-a: http://www.a.com
test-b: http://www.b.com
test-c: http://www.c.com
EOF
urls_config: urls_tests.yml
default_redirect: "Nothing to see!"
post-run: bats ./tests/test_gen.bats

test-default-redirect-url:
name: Default (Redirect URL)
uses: ./.github/workflows/test-reusable.yml
with:
urls_config: not_needed.yml
default_redirect: "http://www.d.com"
post-run: bats ./tests/test_default_url.bats

test-default-message:
name: Default (Message)
uses: ./.github/workflows/test-reusable.yml
with:
urls_config: not_needed.yml
default_redirect: "abc"
post-run: bats ./tests/test_default_msg.bats

# Notes:
# Reusable workflows in the same repo MUST:
# * Be in ./.github/workflows
# * Be referenced (in "uses:") starting with "./",
# i.e. "./.github/workflows/<workflow>"
218 changes: 217 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,218 @@
# gh-pages-url-shortener-action
An ultra-lightweight GitHub Pages URL shortener entirely powered by built-in GitHub Pages (Jekyll) features
> Lightweight [GitHub Pages](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages) URL shortener powered by [GitHub Actions](https://docs.github.com/en/actions).
[![Tests](https://github.com/pndurette/gh-pages-url-shortener-action/actions/workflows/test.yml/badge.svg)](https://github.com/pndurette/gh-pages-url-shortener-action/actions/workflows/test.yml)

## About

* Minimal inside and out: no templates, no layouts, no code
* Uses only built-in GitHub Pages features (powered by [Jekyll](https://jekyllrb.com)) and first-party actions
* Easy setup: add `pndurette/gh-pages-url-shortener-action` to a worflow, create `urls.yml`

See [How it works](#how-it-works).

## Setup

1. Create [new GitHub repository](https://github.com/new)
1. *For example:* `<your account>/url-shortener`
2. Enable GitHub Pages (`<new repo>` > Settings > Pages)
1. *Source:* GitHub Actions
3. [Optional] [Configure custom domain](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site)
4. Create a new GitHub Actions workflow:

<details><summary><code>.github/workflows/deploy.yml</code></summary>
<p>

(This is GitHub's own [GitHub Pages Jekyll](https://github.com/actions/starter-workflows/blob/da484b4eb58a75ee389d1483a295b33c9774ea0f/pages/jekyll-gh-pages.yml) starter workflow with `actions/jekyll-build-page` swapped for this action).

See [Configuration](#configuration) below for action inputs.

```yaml
name: Deploy URL Shortener

on:
# Runs on pushes targeting the default branch
push:
branches: [main]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Generate URL Shortener
uses: pndurette/gh-pages-url-shortener-action@v1
- name: Upload artifact
uses: actions/upload-pages-artifact@v1

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
```
</p>
</details>
5. Create a URL redirect configuration file:
<details><summary><code>.github/urls.yml</code></summary>
<p>
Each `<key>` will be the path redirecting to a url `<value>`. For example:

```yaml
---
abc: "https://google.com"
def: "https://yahoo.com"
xyz: "https://some-other-site.com"
```

Will generate the following links:

* `http://<your site>/abc` will redirect to `https://google.com`
* `http://<your site>/def` will redirect to `https://yahoo.com`
* `http://<your site>/xyz` will redirect to `https://some-other-site.com`

</p>
</details>

6. Push to `main` (watch the action run summary for more info!)

## Configuration

<!--doc_begin-->
### Inputs
|Input|Description|Default|Required|
|-----|-----------|-------|:------:|
|`urls_config`|<p>The path to a YAML file associating redirect keys to URLs, e.g.:</p><pre>---<br />test1: https://www.bookcity.ca/<br />test2: https://www.gladdaybookshop.com<br /></pre>|`.github/urls.yml`|no|
|`default_redirect`|<p>Default behaviour for <code>/</code> or any 404, can be either:<br /> * a URL to redirect to<br /> * a message to display</p>|`Nothing here!`|no|

<!--doc_end-->

## How it works

All the logic is shared between a Jekyll [`_config.yml`](.github/_config.yml) and the action itself in [`action.yml`](action.yml).

### Jekyll

**Jekyll Collections**

Each URL to redirect is created by the action as an individual document defined in a [Collection](https://jekyllrb.com/docs/collections/):

```yaml
# _config.yml
collections:
redirects:
output: true
permalink: /:name
```

*The above reads: "In `_redirects` (Jekyll's convention), generate one file per document (`output: true`) for which the final URL path will be `/:name` (i.e. name of the file, minus the extension)"*

For example, for an entry `link1: "https://google.com"` in `urls.yml`, the action would create `_redirect/link1.yml` as:

```yaml
---
redirect_to: https://google.com
---
```

**The `jekyll-redirect-from` plugin**

The `redirect_to` [front matter](https://jekyllrb.com/docs/front-matter/) variable is provided by the [jekyll-redirect-from](https://github.com/jekyll/jekyll-redirect-from) plugin, which is whitelisted by GitHub Pages:

```yaml
# _config.yml
plugins:
- "jekyll-redirect-from"
```

The plugin will generate an HTML file per Collection document, with every possible client-side way to redirect a url. The `_redirect/link1.yml` file above would be generated by Jekyll to `link1.html` as:

```html
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="https://google.com">
<script>location="https://google.com"</script>
<meta http-equiv="refresh" content="0; url=https://google.com">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="https://google.com">Click here if you are not redirected.</a>
</html>
```

Allowing the it to be hit at `https://<site>/link1`. It does the same for the `index.html` and `404.hml` (for `/` or non-existing path, respetively), which can also be redirects or plain strings (default is `Nothing here!`).

### Action

The [composite](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action) action in [`action.yml`](action.yml) reads `url.yml` and translates it to individual per-URL `.md` file. It will then call the official [`actions/jekyll-build-pages`](https://github.com/actions/jekyll-build-pages) action to generate the content. It also generates a table summary of what was generated.

### Generated files

The generated file hierarchy is minimal. For instance, for a `url.yml` that might contain:

```yaml
---
abc: "https://google.com"
def: "https://yahoo.com"
xyz: "https://some-other-site.com"
```

The action will generate (if the action input `default_redirect` is set to a URL):

```
.
├── 404.md
├── _config.yml
├── _redirects
│   ├── abc.md
│   ├── def.md
│   └── xyz.md
└── index.md
```

And the GitHub Pages-hosted directory will look like:

```
.
├── 404.html
├── abc.html
├── def.html
├── index.html
├── redirects.json
└── xyx.html
```

## License

[The MIT License (MIT)](LICENSE) Copyright © 2023 Pierre Nicolas Durette
Loading

0 comments on commit 75300a5

Please sign in to comment.