diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..418236c4e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,18 @@ +name: integration +on: + schedule: + - cron: 0 2 * * 0-6 +jobs: + integration-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Build and Deploy + uses: JamesIves/github-pages-deploy-action@master + env: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + BRANCH: gh-pages + FOLDER: 'test/build' + BUILD_SCRIPT: npm run-script integrationTest diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..3989b6da8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# .DS_Store +.DS_Store +.idea/ + +# Integration Tests +npm-debug.log* +yarn-debug.log* +yarn-error.log* +test/build \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a8174dd44..27d89633b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM node:10 +FROM cgr.dev/chainguard/wolfi-base:latest -LABEL "com.github.actions.name"="Deploy to Github Pages" -LABEL "com.github.actions.description"="This action will handle the building and deploying process of your project to Github Pages." +LABEL "com.github.actions.name"="Deploy to GitHub Pages" +LABEL "com.github.actions.description"="This action will handle the building and deploying process of your project to GitHub Pages." LABEL "com.github.actions.icon"="git-commit" LABEL "com.github.actions.color"="orange" @@ -9,5 +9,9 @@ LABEL "repository"="http://github.com/JamesIves/gh-pages-github-action" LABEL "homepage"="http://github.com/JamesIves/gh-pages-gh-action" LABEL "maintainer"="James Ives " +# Install git and bash +RUN apk update \ + && apk --no-cache add git bash + ADD entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md index fb77b52c4..075875667 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,88 @@ -# Github Pages Deploy Action :rocket: +# Used By -This Github action will handle the building and deploying process of your project to Github pages. It can be configured to upload your production ready code into any branch you'd like, including `gh-pages` and `docs`. +https://github.com/search?q=org%3Agrails+%22uses%3A+grails%2Fgithub-pages-deploy-action%22+language%3Ayml&type=code + +# GitHub Pages Deploy Action :rocket: + +[![Actions Status](https://github.com/grails/github-pages-deploy-action/workflows/integration/badge.svg)](https://github.com/grails/github-pages-deploy-action/actions) [![View Action](https://img.shields.io/badge/view-action-blue.svg)](https://github.com/marketplace/actions/deploy-to-github-pages) [![Issues](https://img.shields.io/github/issues/JamesIves/github-pages-deploy-action.svg)](https://github.com/grails/github-pages-deploy-action/issues) + +This [GitHub action](https://github.com/features/actions) will handle the building and deploying process of your project to [GitHub Pages](https://pages.github.com/). It can be configured to upload your production ready code into any branch you'd like, including `gh-pages` and `docs`. This action is built on [Node](https://nodejs.org/en/), which means that you can call any optional build scripts your project requires prior to deploying. + +❗️**You can find instructions for using version 1 of the GitHub Actions workflow format [here](https://github.com/grails/github-pages-deploy-action/tree/1.1.3).** ## Getting Started :airplane: -Before you get started you must first create a fresh branch where the action will deploy the files to. You can replace `gh-pages` with whatever branch you'd like to use below. This will create a new orphaned branch which is what Github Pages require. - -```git -git checkout --orphan gh-pages -git rm -rf . -touch README.md -git add README.md -git commit -m 'Initial gh-pages commit' -git push origin gh-pages -``` +You can include the action in your workflow to trigger on any event that [GitHub actions supports](https://help.github.com/en/articles/events-that-trigger-workflows). If the remote branch that you wish to deploy to doesn't already exist the action will create it for you. Your workflow will also need to include the `actions/checkout` step before this workflow runs in order for the deployment to work. + +You can view an example of this below. -Once setup you can then include the action in your workflow to trigger on any built in event that Github supports. +```yml +name: Build and Deploy +on: [push] +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Build and Deploy + uses: grails/github-pages-deploy-action@v2 + env: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + BASE_BRANCH: master # The branch the action should deploy from. + BRANCH: gh-pages # The branch the action should deploy to. + FOLDER: build # The folder the action should deploy. + BUILD_SCRIPT: npm install && npm run-script build # The build script the action should run prior to deploying. ``` -action "Deploy to Github Pages" { - uses = "JamesIves/github-pages-deploy-action@master" - env = { - BUILD_SCRIPT = "npm install && npm run-script build" - BRANCH = "gh-pages" - FOLDER = "build" - COMMIT_EMAIL = "github-pages-deployer@jamesives.dev" - COMMIT_NAME = "Github Pages Deployer" - } - secrets = ["GITHUB_TOKEN"] -} + +If you'd like to make it so the workflow only triggers on push events to specific branches then you can modify the `on` section. You'll still need to specify a `BASE_BRANCH` if you're deploying from a branch other than `master`. + +```yml +on: + push: + branches: + - master ``` ## Configuration 📁 -The `env` portion of the workflow must be configured before the action will work. Below you'll find a description of each one does. +The `env` portion of the workflow **must** be configured before the action will work. You can add these in the `env` section found in the examples above. Any `secrets` must be referenced using the bracket syntax and stored in the GitHub repositories `Settings/Secrets` menu. You can learn more about setting environment variables with GitHub actions [here](https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstepsenv). -| Key | Value Information | Required | -| ------------- | ------------- | ------------- | -| `BUILD_SCRIPT` | If you require a build script to compile your code prior to pushing it you can add the script here. The Docker container which powers the action runs Node which means `npm` commands are valid. If you're using a static site generator I'd suggest building the code prior to pushing it. | **No** | -| `BRANCH` | This is the branch you wish to deploy to, for example `gh-pages` or `docs`. | **Yes** | -| `BASE_BRANCH` | The base branch of your repository which you'd like to checkout prior to deploying. This defaults to `master`. | **No** | -| `FOLDER` | The folder in your repository that you want to deploy. If your build script compiles into a directory named `build` you'd put it in here. | **Yes** | -| `COMMIT_NAME` | Used to sign the commit, this should be your name. | **No** | -| `COMMIT_EMAIL` | Used to sign the commit, this should be your email. | **No** | +Below you'll find a description of what each option does. + +| Key | Value Information | Type | Required | +| ------------- | ------------- | ------------- | ------------- | +| `ACCESS_TOKEN` | In order for GitHub to trigger the rebuild of your page you must provide the action with a GitHub personal access token with read/write permissions. You can [learn more about how to generate one here](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line). This **should be stored as a secret.** | `secrets` | **Yes** | +| `BRANCH` | This is the branch you wish to deploy to, for example `gh-pages` or `docs`. | `env` | **Yes** | +| `FOLDER` | The folder in your repository that you want to deploy. If your build script compiles into a directory named `build` you'd put it here. **Folder paths cannot have a leading `/` or `./`**. | `env` | **Yes** | +| `BASE_BRANCH` | The base branch of your repository which you'd like to checkout prior to deploying. This defaults to `master`. | `env` | **No** | +| `BUILD_SCRIPT` | If you require a build script to compile your code prior to pushing it you can add the script here. The Docker container which powers the action runs Node which means `npm` commands are valid. If you're using a static site generator such as Jekyll I'd suggest compiling the code prior to pushing it to your base branch. | `env` | **No** | +| `CNAME` | If you're using a [custom domain](https://help.github.com/en/articles/using-a-custom-domain-with-github-pages), you will need to add the domain name to the `CNAME` environment variable. If you don't do this GitHub will wipe out your domain configuration after each deploy. This value will look something like this: `jives.dev`. | `env` | **No** | +| `COMMIT_EMAIL` | Used to sign the commit, this should be your email. If not provided it will default to your username. | `env` | **No** | +| `COMMIT_NAME` | Used to sign the commit, this should be your name. If not provided it will default to `username@users.noreply.github.com` | `env` | **No** | + +With the action correctly configured you should see the workflow trigger the deployment under the configured conditions. ![Example](screenshot.png) + +## Releasing a new version + +To release a new version, you need to create a new tag with the version number (prefixed with v). This can be done via +the GitHub Releases page or via the command line. +```console +git tag v3.0 +git push origin v3.0 +``` + +To make major version references work, create a new branch with the major version number (if it does not already exist). +```console +git checkout -b v3 v3.0 +git push origin v3 +``` + +When a new minor version is released, update the major version branch to point to the new release tag. +```console +git checkout v3 +git reset --hard v3.1 +git push --force origin v3 +``` \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 000000000..c2fc60902 --- /dev/null +++ b/action.yml @@ -0,0 +1,9 @@ +name: 'Host on GitHub Pages' +description: 'This action will handle the building and deploying process of your project to GitHub Pages.' +author: 'James Ives ' +runs: + using: 'docker' + image: 'Dockerfile' +branding: + icon: 'git-commit' + color: 'orange' diff --git a/entrypoint.sh b/entrypoint.sh index 1f90c1f17..599a8a2d1 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,34 +1,164 @@ -#!/bin/sh -l +#!/bin/bash + +set -e + +if [ -z "$GH_TOKEN" ] +then + echo "You must provide the action with a GitHub Personal Access Token secret in order to deploy." + exit 1 +fi + if [ -z "$BRANCH" ] then echo "You must provide the action with a branch name it should deploy to, for example gh-pages or docs." exit 1 fi +if [ -z "$DOC_FOLDER" ]; +then + DOC_FOLDER=$BRANCH +fi + +if [ -z "$SKIP_SNAPSHOT" ]; then + SKIP_SNAPSHOT="$BETA" +fi + +if [ -z "$SKIP_LATEST" ]; then + SKIP_LATEST="$SKIP_SNAPSHOT" +fi + if [ -z "$FOLDER" ] then echo "You must provide the action with the folder name in the repository where your compiled page lives." exit 1 fi -# Installs Git. -apt-get update && \ -apt-get install -y git && \ +case "$FOLDER" in /*|./*) + echo "The deployment folder cannot be prefixed with '/' or './'. Instead reference the folder name directly." + exit 1 +esac -# Re-directs to the the Github workspace. +if [ -z "$COMMIT_EMAIL" ] +then + COMMIT_EMAIL="${GITHUB_ACTOR}@users.noreply.github.com" +fi + +if [ -z "$COMMIT_NAME" ] +then + COMMIT_NAME="${GITHUB_ACTOR}" +fi +if [ -z "$TARGET_REPOSITORY" ] +then + TARGET_REPOSITORY="${GITHUB_REPOSITORY}" +fi + +# Directs the action to the the Github workspace. cd $GITHUB_WORKSPACE && \ -# Configures Git and checks out the base branch. -git config --global user.email "${COMMIT_EMAIL:-gh-pages-deploy@jives.dev}" && \ -git config --global user.name "${COMMIT_NAME:-Github Pages Deploy}" && \ -git checkout "${BASE_BRANCH:-master}" && \ +# Configures Git. +git init && \ +git config --global user.email "${COMMIT_EMAIL}" && \ +git config --global user.name "${COMMIT_NAME}" && \ +git config --global http.version HTTP/1.1 && \ + +git config --global http.version HTTP/1.1 +git config --global http.postBuffer 157286400 + +## Initializes the repository path using the access token. +REPOSITORY_PATH="https://${GH_TOKEN}@github.com/${TARGET_REPOSITORY}.git" && \ + +# Checks to see if the remote exists prior to deploying. +# If the branch doesn't exist it gets created here as an orphan. +if [ "$(git ls-remote --heads "$REPOSITORY_PATH" "$BRANCH" | wc -l)" -eq 0 ]; +then + echo "Creating remote branch ${BRANCH} as it doesn't exist..." + mkdir $DOC_FOLDER && \ + cd $DOC_FOLDER && \ + git init && \ + git checkout -b $BRANCH && \ + git remote add origin $REPOSITORY_PATH && \ + touch README.md && \ + git add README.md && \ + git commit -m "Initial ${BRANCH} commit" && \ + git push $REPOSITORY_PATH $BRANCH +else + ## Clone the target repository + git clone "$REPOSITORY_PATH" $DOC_FOLDER --branch $BRANCH --single-branch && \ + cd $DOC_FOLDER +fi + +# Builds the project if a build script is provided. +echo "Running build scripts... $BUILD_SCRIPT" && \ +eval "$BUILD_SCRIPT" && \ -# Builds the project if applicable. -echo "Running build scripts... $BUILD_SCRIPT" -eval "$BUILD_SCRIPT" +if [ -n "$CNAME" ]; then + echo "Generating a CNAME file in in the $PWD directory..." + echo $CNAME > CNAME + git add CNAME +fi + +# Update gh-pages root index page +if [ -f "../$FOLDER/ghpages.html" ]; then + cp "../$FOLDER/ghpages.html" index.html + git add index.html +fi # Commits the data to Github. -git add -f $FOLDER && \ -git commit -m "Deploying $(date +"%T")" && \ -git push origin `git subtree split --prefix $FOLDER master`:$BRANCH --force +if [ -z "$VERSION" ] +then + if [ -z "$SKIP_SNAPSHOT" ] || [ "$SKIP_SNAPSHOT" == "false" ]; then + echo "No Version. Publishing Snapshot of Docs" + if [ -n "${DOC_SUB_FOLDER}" ]; then + mkdir -p snapshot/$DOC_SUB_FOLDER + cp -r "../$FOLDER/." ./snapshot/$DOC_SUB_FOLDER/ + git add snapshot/$DOC_SUB_FOLDER/* + else + mkdir -p snapshot + cp -r "../$FOLDER/." ./snapshot/ + git add snapshot/* + fi + fi +else + if [ -z "$SKIP_LATEST" ] || [ "$SKIP_LATEST" == "false" ] + then + echo "Publishing Latest Docs" + if [ -n "${DOC_SUB_FOLDER}" ]; then + mkdir -p latest/$DOC_SUB_FOLDER + cp -r "../$FOLDER/." ./latest/$DOC_SUB_FOLDER/ + git add latest/$DOC_SUB_FOLDER/* + else + mkdir -p latest + cp -r "../$FOLDER/." ./latest/ + git add latest/* + fi + fi + + echo "Publishing $VERSION of Docs" + majorVersion=${VERSION:0:4} + majorVersion="${majorVersion}x" + + if [ -n "${DOC_SUB_FOLDER}" ]; then + mkdir -p "$VERSION/$DOC_SUB_FOLDER" + cp -r "../$FOLDER/." "./$VERSION/$DOC_SUB_FOLDER" + git add "$VERSION/$DOC_SUB_FOLDER/*" + else + mkdir -p "$VERSION" + cp -r "../$FOLDER/." "./$VERSION/" + git add "$VERSION/*" + fi + + if [ -n "${DOC_SUB_FOLDER}" ]; then + mkdir -p "$majorVersion/$DOC_SUB_FOLDER" + cp -r "../$FOLDER/." "./$majorVersion/$DOC_SUB_FOLDER" + git add "$majorVersion/$DOC_SUB_FOLDER/*" + else + mkdir -p "$majorVersion" + cp -r "../$FOLDER/." "./$majorVersion/" + git add "$majorVersion/*" + fi +fi + +git commit -m "Deploying to ${BRANCH} - $(date +"%T")" --quiet && \ +git push "https://$GITHUB_ACTOR:$GH_TOKEN@github.com/$TARGET_REPOSITORY.git" gh-pages || true && \ +echo "Deployment successful!" diff --git a/package.json b/package.json new file mode 100644 index 000000000..50f6c50ef --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "name": "github-pages-deploy-action", + "description": "GitHub action for building a project and deploying it to GitHub pages.", + "license": "MIT", + "repository": "https://github.com/grails/github-pages-deploy-action", + "scripts": { + "integrationTest": "mkdir test/build && cp test/image.jpg test/build/image.jpg && cp test/index.html test/build/index.html" + } +} diff --git a/screenshot.png b/screenshot.png index 7b1095a82..4ddabd021 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/test/image.jpg b/test/image.jpg new file mode 100644 index 000000000..16bcd3d21 Binary files /dev/null and b/test/image.jpg differ diff --git a/test/index.html b/test/index.html new file mode 100644 index 000000000..024fc79a4 --- /dev/null +++ b/test/index.html @@ -0,0 +1,32 @@ + + + + + Integration Test + + + + + +
+ + \ No newline at end of file