25 KiB
GitHub Actions for GitHub Pages
This is a GitHub Action to deploy your static files to GitHub Pages. This deploy action can be combined simply and freely with Static Site Generators. (Hugo, MkDocs, Gatsby, GitBook, mdBook, etc.)
The next example step will deploy ./public
directory to the remote gh-pages
branch.
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
# PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
Three tokens are supported.
Token | Private repo | Public repo | Protocol | Setup |
---|---|---|---|---|
GITHUB_TOKEN |
✅️ | (1) | HTTPS | Unnecessary |
PERSONAL_TOKEN |
✅️ | ✅️ | HTTPS | Necessary |
ACTIONS_DEPLOY_KEY |
✅️ | ✅️ | SSH | Necessary |
- Currently, GitHub Actions does not support to trigger a GitHub Pages build event using GITHUB_TOKEN on a public repository.
Do you want to skip the docker build step? OK, the script mode is available.
- name: Deploy
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
SCRIPT_MODE: true
run: |
wget https://raw.githubusercontent.com/peaceiris/actions-gh-pages/v2/entrypoint.sh
bash ./entrypoint.sh
Table of Contents
Getting started
(1) Add SSH deploy key
Generate your deploy key with the following command.
ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
# You will get 2 files:
# gh-pages.pub (public key)
# gh-pages (private key)
Next, Go to Repository Settings
- Go to Deploy Keys and add your public key with the Allow write access
- Go to Secrets and add your private key as
ACTIONS_DEPLOY_KEY
Add your public key | Success |
---|---|
Add your private key | Success |
---|---|
(2) Create your workflow
Add your workflow setting YAML file .github/workflows/gh-pages.yml
and push to the default branch.
⭐️ Repository type - Project
An example workflow for Hugo.
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
# with:
# submodules: true
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.59.1'
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
The above example is for Project Pages sites. (<username>/<project_name>
repository)
Actions log overview | Build step log |
---|---|
Deploy step log | GitHub Pages log |
---|---|
⭐️ Repository type - User and Organization
For User and Organization Pages sites (<username>/<username>.github.io
repository),
we have to set master
branch to PUBLISH_BRANCH
.
on:
push:
branches:
- source # default branch
PUBLISH_BRANCH: master # deploying branch
Options
⭐️ Pull action image from Docker Hub
You can pull a public docker image from Docker Hub.
By pulling docker images, you can reduce the overall execution time of your workflow. In addition, latest
tag is provided.
- uses: peaceiris/actions-gh-pages@v2
+ uses: docker://peaceiris/gh-pages:v2
⭐️ PERSONAL_TOKEN
Generate a personal access token (repo
) and add it to Secrets as PERSONAL_TOKEN
, it works as well as ACTIONS_DEPLOY_KEY
.
- ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
+ PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
⭐️ GITHUB_TOKEN
⚠️ NOTES:
GITHUB_TOKEN
works only on a private repository.This action supports
GITHUB_TOKEN
but it has some problems to deploy to GitHub Pages. GitHub team is investigating that. See Issue #9
- ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
⭐️ Suppressing empty commits
By default, a commit will always be generated and pushed to the PUBLISH_BRANCH
, even if nothing changed. If you want to suppress this behavior, set the optional parameter emptyCommits
to false
. cf. Issue #21
For example:
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
emptyCommits: false
⭐️ Keeping existing files
By default, existing files in the publish branch are removed before adding the ones from publish dir. If you want the action to add new files but leave existing ones untouched, set the optional parameter keepFiles
to true
.
For example:
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
keepFiles: true
⭐️ Deploy to external repository
By default, your files are published to the repository which is running this action.
If you want to publish to another repository on GitHub, set the environment variable EXTERNAL_REPOSITORY
to <username>/<external-repository>
.
This option is available from v2.5.0
.
For example:
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
EXTERNAL_REPOSITORY: username/external-repository
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
You can use ACTIONS_DEPLOY_KEY
or PERSONAL_TOKEN
.
When you use ACTIONS_DEPLOY_KEY
, set your private key to the repository which includes this action and set your public key to your external repository.
Be careful, GITHUB_TOKEN
has no permission to access to external repositories.
⭐️ Force orphan
From v2.6.0
, we can set the forceOrphan: true
option.
This allows you to make your publish branch with only the latest commit.
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
forceOrphan: true
⭐️ Set Git username and email
Set custom git config user.name
and git config user.email
.
A commit is always created with the same user.
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
username: "iris"
useremail: "iris@peaceiris.com"
⭐️ Set custom commit message
Set custom commit message.
When we create a commit with a message docs: Update some post
, a deployment commit will be generated with a message docs: Update some post ${GITHUB_SHA}
.
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
commitMessage: ${{ github.event.head_commit.message }}
⭐️ Create Git tag
Here is an example workflow.
name: github pages
on:
push:
branches:
- master
tags:
- 'v*.*.*'
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Some build
- name: Prepare tag
id: prepare_tag
if: startsWith(github.ref, 'refs/tags/')
run: |
TAG_NAME="${GITHUB_REF##refs/tags/}"
echo "::set-output name=tag_name::${TAG_NAME}"
echo "::set-output name=deploy_tag_name::deploy-${TAG_NAME}"
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
with:
tagName: ${{ steps.prepare_tag.outputs.deploy_tag_name }}
tagMessage: 'Deployment ${{ steps.prepare_tag.outputs.tag_name }}'
Commands on a local machine.
$ # On the master branch
$ git tag -a "v1.2.3" -m "Release v1.2.3"
$ git push origin "v1.2.3"
$ # After deployment
$ git fetch origin
$ git tag
deploy-v1.2.3 # Tag on the gh-pages branch
v1.2.3 # Tag on the master branch
We can set tagOverwrite
option to true
for overwriting a tag.
⭐️ Script mode
From v2.5.0
, we can run this action as a shell script.
There is no Docker build or pull step, so it will start immediately.
ACTIONS_DEPLOY_KEY
requiresSCRIPT_MODE: true
*_TOKEN
do not requireSCRIPT_MODE
- name: Deploy
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
SCRIPT_MODE: true
run: |
wget https://raw.githubusercontent.com/peaceiris/actions-gh-pages/v2/entrypoint.sh
bash ./entrypoint.sh
Tips and FAQ
⭐️ Use the latest and specific release
We recommend you to use the latest and specific release of this action for stable CI/CD. It is useful to watch this repository (release only) to check the latest release of this action.
⭐️ How to add CNAME
Most of the Static Site Generators support CNAME
as a static file.
The same may be said of other files (.nojekyll
, BingSiteAuth.xml
, robots.txt
, etc.). It is better to manage those files by Static Site Generators.
Does not your static site generator deal with the static files? No problem, you can add the file like the following.
- name: Build
run: |
buildcommand
cp ./path/to/CNAME ./public/CNAME
- name: Deploy
⭐️ Deployment completed but you cannot read
Does your PUBLISH_DIR
contain files or directories that name starts with an underscore? (_modules
, _sources
and _next
, etc.)
GitHub Pages does not read those by default.
Please add .nojekyll
file to PUBLISH_DIR
.
It is now possible to completely bypass Jekyll processing on GitHub Pages by creating a file named
.nojekyll
in the root of your pages repo and pushing it to GitHub. This should only be necessary if your site uses files or directories that start with underscores since Jekyll considers these to be special resources and does not copy them to the final site.
Does not your static site generator deal with the static files? No problem, you can add the file like the following.
- name: Build
run: |
buildcommand
touch ./public/.nojekyll
- name: Deploy
Examples
⭐️ Static Site Generators with Node.js
hexo, gitbook, vuepress, react-static, gridsome, etc.
Premise: Dependencies are managed by package.json
and package-lock.json
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci
- run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
⭐️ Gatsby
An example for Gatsby (Gatsby.js) project with gatsby-starter-blog
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci
- run: npm run format
- run: npm run test
- run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public
⭐️ React and Next
An example for Next.js (React.js) project with create-next-app
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Get yarn cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- run: yarn install
- run: yarn build
- run: yarn export
- run: touch ./out/.nojekyll
- name: deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./out
⭐️ Vue and Nuxt
An example for Nuxt.js (Vue.js) project with create-nuxt-app
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci
- run: npm test
- run: npm run generate
- name: deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./dist
⭐️ Static Site Generators with Python
Premise: Dependencies are managed by requirements.txt
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: '3.6'
architecture: 'x64'
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r ./requirements.txt
- run: mkdocs build
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./site
⭐️ mdBook (Rust)
An example GitHub Actions workflow to deploy rust-lang/mdBook site to GitHub Pages.
name: github pages
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: '0.3.5'
# mdbook-version: 'latest'
- run: mdbook build
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./book
⭐️ Flutter Web
An exapmle workflow for Flutter web project. Setup Flutter with subosito/flutter-action.
peanut | Dart Package is also useful.
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: Setup Flutter
uses: subosito/flutter-action@v1
with:
channel: 'beta'
- name: Install
run: |
flutter config --enable-web
flutter pub get
- name: Build
run: flutter build web
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./build/web
⭐️ Elm
An exapmle workflow for Elm with justgook/setup-elm.
name: github pages
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Elm
uses: justgook/setup-elm@v1
- name: Make
run: elm make --optimize src/Main.elm
- name: Move files
run: |
mkdir ./public
mv ./index.html ./public/
# If you have non-minimal setup with some assets and separate html/js files,
# provide --output=<output-file> option for `elm make` and remove this step
- name: Deploy
uses: peaceiris/actions-gh-pages@v2
env:
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
PUBLISH_BRANCH: gh-pages
PUBLISH_DIR: ./public