Compare commits

..

No commits in common. "main" and "v2.1.0" have entirely different histories.
main ... v2.1.0

89 changed files with 251 additions and 18791 deletions

View File

@ -1,35 +0,0 @@
{
"name": "Node.js",
"image": "docker.pkg.github.com/peaceiris/actions-gh-pages/dev:latest",
// Use 'settings' to set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created in the array below.
"extensions": [
"bungcip.better-toml",
"EditorConfig.EditorConfig",
"donjayamanne.githistory",
"eamodio.gitlens",
"oderwat.indent-rainbow",
"yzhang.markdown-all-in-one",
"shd101wyy.markdown-preview-enhanced",
"christian-kohler.path-intellisense",
"lfs.vscode-emacs-friendly",
"ms-azuretools.vscode-docker",
"dbaeumer.vscode-eslint",
"firsttris.vscode-jest-runner",
"VisualStudioExptTeam.vscodeintellicode"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [3000],
// Specifies a command that should be run after the container has been created.
"postCreateCommand": "npm ci",
// Comment out the next line to run as root instead.
// "remoteUser": "runner"
}

View File

@ -1,2 +1,7 @@
.*
*
.git
.github
.hadolint.yaml
LICENSE
README.md
action.yml
images

View File

@ -1,13 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[Makefile]
indent_size = 4
indent_style = tab

3
.envrc
View File

@ -1,3 +0,0 @@
nvmrc=~/.nvm/nvm.sh
source $nvmrc
nvm use

View File

@ -1,26 +0,0 @@
{
"env": {
"commonjs": true,
"es6": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended",
"plugin:prettier/recommended"
],
"plugins": ["@typescript-eslint"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2019
},
"rules": {
}
}

3
.github/CODEOWNERS vendored
View File

@ -1,3 +0,0 @@
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
* @peaceiris

9
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,9 @@
# These are supported funding model platforms
# github: peaceiris
patreon: peaceiris
issuehunt: peaceiris
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: # Replace with a single custom sponsorship URL

View File

@ -1,52 +0,0 @@
name: User Support
description: Questions for this action
title: "support: "
labels: support
assignees: peaceiris
body:
- type: markdown
attributes:
value:
Please note we will close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information.
- type: checkboxes
attributes:
label: Checklist
description: Checklist before creating an issue.
options:
- label: "I am using the latest version of this action."
required: true
- label: "I have read the latest README and followed the instructions."
required: true
- label: "I have read the latest GitHub Actions official documentation and learned the basic spec and concepts."
required: true
- type: textarea
attributes:
label: Describe your question
description: A clear and concise description of what the question is.
validations:
required: true
- type: textarea
attributes:
label: Relevant links
description:
Links to your public repository, YAML config file, and YAML workflow file.
Please use [a permanent link](https://docs.github.com/en/github/managing-files-in-a-repository/managing-files-on-github/getting-permanent-links-to-files), not a default branch.
render: markdown
value: |
Public repository:
YAML config:
YAML workflow:
validations:
required: true
- type: textarea
attributes:
label: Relevant log output
description: Copy and paste any relevant log output here.
validations:
required: false
- type: textarea
attributes:
label: Additional context.
description: Write any other context about the question here.
validations:
required: false

View File

@ -1,52 +0,0 @@
name: Bug Report
description: Try the User Support Issue Template first.
title: 'bug: '
labels: bug
assignees: peaceiris
body:
- type: markdown
attributes:
value:
Please note we will close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information.
- type: checkboxes
attributes:
label: Checklist
description: Checklist before creating an issue.
options:
- label: "I am using the latest version of this action."
required: true
- label: "I have read the latest README and followed the instructions."
required: true
- label: "I have read the latest GitHub Actions official documentation and learned the basic spec and concepts."
required: true
- type: textarea
attributes:
label: "Describe the bug"
description: "A clear and concise description of what the bug is."
validations:
required: true
- type: textarea
attributes:
label: Relevant links
description:
Links to your public repository, YAML config file, and YAML workflow file.
Please use [a permanent link](https://docs.github.com/en/github/managing-files-in-a-repository/managing-files-on-github/getting-permanent-links-to-files), not a default branch.
render: markdown
value: |
Public repository:
YAML config:
YAML workflow:
validations:
required: true
- type: textarea
attributes:
label: Relevant log output
description: Copy and paste any relevant log output here.
validations:
required: false
- type: textarea
attributes:
label: Additional context.
description: Write any other context about the question here.
validations:
required: false

View File

@ -1,45 +0,0 @@
name: Proposal
description: Suggest an idea for this project
title: 'proposal: '
labels: proposal
assignees: peaceiris
body:
- type: markdown
attributes:
value:
Please note we will close your issue without comment if you do not fill out the issue checklist below and provide ALL the requested information.
- type: checkboxes
attributes:
label: Checklist
description: Checklist before creating an issue.
options:
- label: "I am using the latest version of this action."
required: true
- label: "I have read the latest README and followed the instructions."
required: true
- label: "I have read the latest GitHub Actions official documentation and learned the basic spec and concepts."
required: true
- type: textarea
attributes:
label: "Describe your proposal"
description: "A clear and concise description of what the proposal is."
validations:
required: true
- type: textarea
attributes:
label: "Describe the solution you'd like"
description: "A clear and concise description of what you want to happen."
validations:
required: true
- type: textarea
attributes:
label: "Describe alternatives you've considered"
description: "A clear and concise description of any alternative solutions or features you've considered."
validations:
required: false
- type: textarea
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here."
validations:
required: false

View File

@ -1,14 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Discussions
url: https://github.com/peaceiris/actions-gh-pages/discussions
about: Ask casual questions or share your story about the GitHub Pages Action.
- name: GitHub Actions - GitHub Support Community Forum
url: https://github.community/c/code-to-cloud/github-actions/41
about: Please ask questions about GitHub Actions here.
- name: GitHub Pages Documentation
url: https://docs.github.com/en/pages
about: GitHub Pages official documentation here.
- name: GitHub Actions Documentation
url: https://docs.github.com/en/actions
about: GitHub Actions official documentation here.

View File

@ -1,36 +0,0 @@
labels:
- name: resolved
labeled:
issue:
body: |
This issue has been **LOCKED** because of it being resolved!
The issue has been fixed and is therefore considered resolved.
If you still encounter this or it has changed, open a new issue instead of responding to solved ones.
action: close
locking: lock
lock_reason: resolved
- name: inactive
labeled:
issue:
body: |
This issue has been marked as inactive.
If you still encounter this or it has changed, add a comment to provide further information.
- name: stale
labeled:
issue:
body: |
This issue has been **LOCKED** because of it being old.
If you still encounter this or it has changed, open a new issue.
action: close
locking: lock
lock_reason: resolved
- name: duplicate
labeled:
issue:
body: |
This issue has been closed because of duplication.
action: close
locking: lock
lock_reason: resolved

20
.github/labeler.yml vendored
View File

@ -1,20 +0,0 @@
cicd:
- .github/workflows/*
dependencies:
- .nvmrc
- package.json
- package-lock.json
documentation:
- README.md
test:
- __tests__
docker:
- .devcontainer/*
- .dockerignore
- Dockerfile
- Makefile
- docker-compose.yml

View File

@ -1,24 +0,0 @@
name: "Code Scanning"
on:
push:
branches:
- main
pull_request:
jobs:
CodeQL-Build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View File

@ -1,16 +0,0 @@
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on:
pull_request:
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4

47
.github/workflows/docker-image-ci.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: docker image ci
on:
push:
branches:
- master
- 'release-v*'
jobs:
test:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@master
- name: build
env:
DOCKER_IMAGE: docker.pkg.github.com/${{ github.repository }}/action:latest
run: |
docker build . --file Dockerfile --tag ${DOCKER_IMAGE} ||
(echo -e "\e[31m[${GITHUB_WORKFLOW}] failed to build\e[m" && exit 1)
# - name: push latest image
# if: endsWith(github.ref, 'master')
# env:
# DOCKER_IMAGE: docker.pkg.github.com/${{ github.repository }}/action:latest
# PKG_GITHUB_TOKEN: ${{ secrets.PKG_GITHUB_TOKEN }}
# run: |
# echo ${PKG_GITHUB_TOKEN} | docker login docker.pkg.github.com -u ${GITHUB_ACTOR} --password-stdin &&
# docker push ${DOCKER_IMAGE} &&
# docker logout
shellcheck:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@master
- name: shellcheck
run: shellcheck ./entrypoint.sh
hadolint:
runs-on: macOS-10.14
steps:
- uses: actions/checkout@master
- name: hadolint
run: |
brew install hadolint
hadolint ./Dockerfile

View File

@ -1,27 +0,0 @@
name: Label Commenter
on:
issues:
types:
- labeled
- unlabeled
pull_request_target:
types:
- labeled
- unlabeled
permissions:
contents: read
issues: write
pull-requests: write
jobs:
comment:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Label Commenter
uses: peaceiris/actions-label-commenter@v1
env:
RUNNER_DEBUG: 1

View File

@ -1,22 +0,0 @@
name: "Pull Request Labeler"
on:
pull_request_target:
jobs:
triage:
runs-on: ubuntu-22.04
timeout-minutes: 1
permissions: {}
steps:
# https://github.com/peaceiris/actions-github-app-token
- uses: peaceiris/actions-github-app-token@v1.1.6
id: app
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
# https://github.com/actions/labeler
- uses: actions/labeler@v4
with:
repo-token: "${{ steps.app.outputs.token }}"

View File

@ -1,14 +0,0 @@
name: Check Pages Status
on: page_build
jobs:
pages-status-check:
runs-on: ubuntu-22.04
steps:
- name: check status
run: |
status = '${{ github.event.build.status }}'
errormsg = '${{ github.event.build.error.message }}'
assert status == 'built', 'Status: {status}\nError: {errormsg}'.format(status, errormsg)
shell: python

View File

@ -1,17 +0,0 @@
name: Purge image cache
on:
schedule:
- cron: '54 18 * * */7'
workflow_dispatch:
jobs:
purge:
runs-on: ubuntu-22.04
steps:
- run: >
curl -sL https://github.com/${GITHUB_REPOSITORY} |
grep -oE '<img src="https?://camo.githubusercontent.com/[^"]+' |
sed -e 's/<img src="//' |
xargs -I % curl -sX PURGE %

View File

@ -1,16 +0,0 @@
name: Release
on:
push:
tags:
- 'v3.*.*'
jobs:
release:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
# https://github.com/peaceiris/workflows/blob/main/create-release-npm/action.yml
- uses: peaceiris/workflows/create-release-npm@v0.20.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,182 +0,0 @@
name: 'Test'
on:
push:
branches:
- main
paths-ignore:
- '*.md'
pull_request:
paths-ignore:
- '*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- 'ubuntu-22.04'
- 'ubuntu-20.04'
- 'ubuntu-latest'
- 'macos-latest'
- 'windows-latest'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: peaceiris/workflows/setup-node@v0.20.1
with:
node-version-file: ".nvmrc"
- name: Dump version
run: |
node -v
npm --version
git --version
- run: npm ci --ignore-scripts
- name: npm audit
if: startsWith(matrix.os, 'ubuntu-22.04')
run: |
npm audit > ./audit.log || true
if ! [ "$(cat ./audit.log | wc -l)" = 1 ]; then
echo "::warning::$(cat ./audit.log)"
fi
rm ./audit.log
- name: Run prettier
if: startsWith(matrix.os, 'ubuntu-22.04')
run: npm run format:check
- name: Run eslint
if: startsWith(matrix.os, 'ubuntu-22.04')
run: npm run lint
- run: npm test
- name: Upload test coverage as artifact
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.os }}
path: coverage
- uses: codecov/codecov-action@v4
- name: Run ncc
run: npm run build
- name: Remove lint-staged husky
if: ${{ github.ref == 'refs/heads/main' }}
run: |
npm uninstall lint-staged husky
git checkout package-lock.json package.json
- name: Setup mdBook
if: ${{ github.ref == 'refs/heads/main' }}
uses: peaceiris/actions-mdbook@v1.2.0
with:
mdbook-version: '0.4.5'
- name: Build site
if: ${{ github.ref == 'refs/heads/main' }}
working-directory: ./test_projects/mdbook
run: mdbook build
- name: Deploy
if: |
startsWith(matrix.os, 'ubuntu-latest') &&
github.ref == 'refs/heads/main' && github.event.repository.fork == false
uses: ./
with:
# deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_branch: gh-pages
publish_dir: ./test_projects/mdbook/book
# external_repository: ''
allow_empty_commit: true
# keep_files: true
# force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
# commit_message: ${{ github.event.head_commit.message }}
cname: 'actions-gh-pages.peaceiris.com'
- name: Deploy
if: |
startsWith(matrix.os, 'macos') &&
github.ref == 'refs/heads/main' && github.event.repository.fork == false
uses: ./
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
# github_token: ${{ secrets.GITHUB_TOKEN }}
# personal_token: ${{ secrets.PERSONAL_TOKEN }}
publish_branch: gh-pages-macos
publish_dir: ./test_projects/mdbook/book
# external_repository: ''
allow_empty_commit: true
# keep_files: true
# force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
# commit_message: ${{ github.event.head_commit.message }}
- name: Deploy
if: |
startsWith(matrix.os, 'windows') &&
github.ref == 'refs/heads/main' && github.event.repository.fork == false
uses: ./
with:
# deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
# personal_token: ${{ secrets.PERSONAL_TOKEN }}
publish_branch: gh-pages-windows
publish_dir: ./test_projects/mdbook/book
# external_repository: ''
allow_empty_commit: true
# keep_files: true
# force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
# commit_message: ${{ github.event.head_commit.message }}
- name: Deploy
if: |
startsWith(matrix.os, 'ubuntu-20.04') &&
github.ref == 'refs/heads/main' && github.event.repository.fork == false
uses: ./
with:
# deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages-ubuntu-20.04
publish_dir: ./test_projects/mdbook/book
# external_repository: ''
allow_empty_commit: true
# keep_files: true
# force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
# commit_message: ${{ github.event.head_commit.message }}
- name: Deploy
if: |
startsWith(matrix.os, 'ubuntu-22.04') &&
github.ref == 'refs/heads/main' && github.event.repository.fork == false
uses: ./
with:
# deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages-ubuntu-22.04
publish_dir: ./test_projects/mdbook/book
# external_repository: ''
allow_empty_commit: true
# keep_files: true
# force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
# commit_message: ${{ github.event.head_commit.message }}

View File

@ -1,22 +0,0 @@
name: Update major tag
on:
release:
types: [released]
jobs:
update:
runs-on: ubuntu-22.04
timeout-minutes: 1
steps:
- uses: actions/checkout@v4
- name: Update major tag
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git"
export TAG_NAME="${GITHUB_REF##refs/tags/}"
export TAG_MAJOR="${TAG_NAME%%.*}"
git tag --force -a "${TAG_MAJOR}" -m "Release ${TAG_NAME}"
git push --force origin "${TAG_MAJOR}"

6
.gitignore vendored
View File

@ -1,6 +0,0 @@
.DS_Store
coverage
.npm
.eslintcache
.env
node_modules

2
.hadolint.yaml Normal file
View File

@ -0,0 +1,2 @@
ignored:
- DL3018

1
.husky/.gitignore vendored
View File

@ -1 +0,0 @@
_

View File

@ -1,2 +0,0 @@
npm install
git remote prune origin

View File

@ -1 +0,0 @@
npx lint-staged

1
.npmrc
View File

@ -1 +0,0 @@
engine-strict=true

1
.nvmrc
View File

@ -1 +0,0 @@
20.11.1

View File

@ -1,2 +0,0 @@
node_modules/
lib/

View File

@ -1,11 +0,0 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid",
"parser": "typescript"
}

1
.vscode/.gitignore vendored
View File

@ -1 +0,0 @@
*.log

View File

@ -1,4 +0,0 @@
{
"git.ignoreLimitWarning": true,
"deno.enable": false
}

File diff suppressed because it is too large Load Diff

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM alpine:3.10.2
RUN apk add --no-cache \
bash \
git \
openssh-client \
ca-certificates && \
rm -rf /var/lib/apt/lists/*
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

1259
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
/* CSS */

View File

@ -1 +0,0 @@
// JavaScript

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>

View File

@ -1 +0,0 @@
/* CSS */

View File

@ -1 +0,0 @@
// JavaScript

View File

@ -1 +0,0 @@
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners

View File

@ -1 +0,0 @@
<!-- issue template -->

View File

@ -1,7 +0,0 @@
# dependabot config
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily

View File

@ -1 +0,0 @@
name: 'Test'

View File

@ -1 +0,0 @@
/* CSS */

View File

@ -1 +0,0 @@
// JavaScript

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>

View File

@ -1 +0,0 @@
/* CSS */

View File

@ -1 +0,0 @@
// JavaScript

View File

@ -1,189 +0,0 @@
// import * as main from '../src/main';
import {Inputs} from '../src/interfaces';
import {showInputs, getInputs} from '../src/get-inputs';
import os from 'os';
import fs from 'fs';
import yaml from 'js-yaml';
beforeEach(() => {
jest.resetModules();
process.stdout.write = jest.fn();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const doc: any = yaml.load(fs.readFileSync(__dirname + '/../action.yml', 'utf8'));
Object.keys(doc.inputs).forEach(name => {
const envVar = `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
process.env[envVar] = doc.inputs[name]['default'];
});
});
afterEach(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const doc: any = yaml.load(fs.readFileSync(__dirname + '/../action.yml', 'utf8'));
Object.keys(doc.inputs).forEach(name => {
const envVar = `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
console.debug(`delete ${envVar}\t${process.env[envVar]}`);
delete process.env[envVar];
});
});
// Assert that process.stdout.write calls called only with the given arguments.
// cf. https://github.com/actions/toolkit/blob/8b0300129f08728419263b016de8630f1d426d5f/packages/core/__tests__/core.test.ts
function assertWriteCalls(calls: string[]): void {
expect(process.stdout.write).toHaveBeenCalledTimes(calls.length);
for (let i = 0; i < calls.length; i++) {
expect(process.stdout.write).toHaveBeenNthCalledWith(i + 1, calls[i]);
}
}
function getInputsLog(authMethod: string, inps: Inputs): string {
return `\
[INFO] ${authMethod}: true
[INFO] PublishBranch: ${inps.PublishBranch}
[INFO] PublishDir: ${inps.PublishDir}
[INFO] DestinationDir: ${inps.DestinationDir}
[INFO] ExternalRepository: ${inps.ExternalRepository}
[INFO] AllowEmptyCommit: ${inps.AllowEmptyCommit}
[INFO] KeepFiles: ${inps.KeepFiles}
[INFO] ForceOrphan: ${inps.ForceOrphan}
[INFO] UserName: ${inps.UserName}
[INFO] UserEmail: ${inps.UserEmail}
[INFO] CommitMessage: ${inps.CommitMessage}
[INFO] FullCommitMessage: ${inps.FullCommitMessage}
[INFO] TagName: ${inps.TagName}
[INFO] TagMessage: ${inps.TagMessage}
[INFO] EnableJekyll (DisableNoJekyll): ${inps.DisableNoJekyll}
[INFO] CNAME: ${inps.CNAME}
[INFO] ExcludeAssets ${inps.ExcludeAssets}
`;
}
describe('showInputs()', () => {
// eslint-disable-next-line jest/expect-expect
test('print all inputs DeployKey', () => {
process.env['INPUT_DEPLOY_KEY'] = 'test_deploy_key';
const inps: Inputs = getInputs();
showInputs(inps);
const authMethod = 'DeployKey';
const test = getInputsLog(authMethod, inps);
assertWriteCalls([`${test}${os.EOL}`]);
});
// eslint-disable-next-line jest/expect-expect
test('print all inputs GithubToken', () => {
delete process.env['INPUT_DEPLOY_KEY'];
process.env['INPUT_GITHUB_TOKEN'] = 'test_github_token';
const inps: Inputs = getInputs();
showInputs(inps);
const authMethod = 'GithubToken';
const test = getInputsLog(authMethod, inps);
assertWriteCalls([`${test}${os.EOL}`]);
});
// eslint-disable-next-line jest/expect-expect
test('print all inputs PersonalToken', () => {
delete process.env['INPUT_DEPLOY_KEY'];
delete process.env['INPUT_GITHUB_TOKEN'];
process.env['INPUT_PERSONAL_TOKEN'] = 'test_personal_token';
const inps: Inputs = getInputs();
showInputs(inps);
const authMethod = 'PersonalToken';
const test = getInputsLog(authMethod, inps);
assertWriteCalls([`${test}${os.EOL}`]);
});
});
describe('getInputs()', () => {
test('get default inputs', () => {
process.env['INPUT_DEPLOY_KEY'] = 'test_deploy_key';
const inps: Inputs = getInputs();
expect(inps.DeployKey).toMatch('test_deploy_key');
expect(inps.GithubToken).toMatch('');
expect(inps.PersonalToken).toMatch('');
expect(inps.PublishBranch).toMatch('gh-pages');
expect(inps.PublishDir).toMatch('public');
expect(inps.DestinationDir).toMatch('');
expect(inps.ExternalRepository).toMatch('');
expect(inps.AllowEmptyCommit).toBe(false);
expect(inps.KeepFiles).toBe(false);
expect(inps.ForceOrphan).toBe(false);
expect(inps.UserName).toMatch('');
expect(inps.UserEmail).toMatch('');
expect(inps.CommitMessage).toMatch('');
expect(inps.FullCommitMessage).toMatch('');
expect(inps.TagName).toMatch('');
expect(inps.TagMessage).toMatch('');
expect(inps.DisableNoJekyll).toBe(false);
expect(inps.CNAME).toMatch('');
expect(inps.ExcludeAssets).toMatch('.github');
});
test('get spec inputs', () => {
// process.env['INPUT_DEPLOY_KEY'] = 'test_deploy_key';
process.env['INPUT_GITHUB_TOKEN'] = 'test_github_token';
process.env['INPUT_PERSONAL_TOKEN'] = 'test_personal_token';
process.env['INPUT_PUBLISH_BRANCH'] = 'master';
process.env['INPUT_PUBLISH_DIR'] = 'out';
process.env['INPUT_DESTINATION_DIR'] = 'subdir';
process.env['INPUT_EXTERNAL_REPOSITORY'] = 'user/repo';
process.env['INPUT_ALLOW_EMPTY_COMMIT'] = 'true';
process.env['INPUT_KEEP_FILES'] = 'true';
process.env['INPUT_FORCE_ORPHAN'] = 'true';
process.env['INPUT_USER_NAME'] = 'username';
process.env['INPUT_USER_EMAIL'] = 'github@github.com';
process.env['INPUT_COMMIT_MESSAGE'] = 'feat: Add new feature';
process.env['INPUT_FULL_COMMIT_MESSAGE'] = 'feat: Add new feature';
process.env['INPUT_TAG_NAME'] = 'deploy-v1.2.3';
process.env['INPUT_TAG_MESSAGE'] = 'Deployment v1.2.3';
process.env['INPUT_DISABLE_NOJEKYLL'] = 'true';
process.env['INPUT_CNAME'] = 'github.com';
process.env['INPUT_EXCLUDE_ASSETS'] = '.github';
const inps: Inputs = getInputs();
expect(inps.DeployKey).toMatch('');
expect(inps.GithubToken).toMatch('test_github_token');
expect(inps.PersonalToken).toMatch('test_personal_token');
expect(inps.PublishBranch).toMatch('master');
expect(inps.PublishDir).toMatch('out');
expect(inps.DestinationDir).toMatch('subdir');
expect(inps.ExternalRepository).toMatch('user/repo');
expect(inps.AllowEmptyCommit).toBe(true);
expect(inps.KeepFiles).toBe(true);
expect(inps.ForceOrphan).toBe(true);
expect(inps.UserName).toMatch('username');
expect(inps.UserEmail).toMatch('github@github.com');
expect(inps.CommitMessage).toMatch('feat: Add new feature');
expect(inps.FullCommitMessage).toMatch('feat: Add new feature');
expect(inps.TagName).toMatch('deploy-v1.2.3');
expect(inps.TagMessage).toMatch('Deployment v1.2.3');
expect(inps.DisableNoJekyll).toBe(true);
expect(inps.CNAME).toMatch('github.com');
expect(inps.ExcludeAssets).toMatch('.github');
});
test('get spec inputs enable_jekyll', () => {
process.env['INPUT_ENABLE_JEKYLL'] = 'true';
const inps: Inputs = getInputs();
expect(inps.DisableNoJekyll).toBe(true);
});
test('throw error enable_jekyll or disable_nojekyll', () => {
process.env['INPUT_DEPLOY_KEY'] = 'test_deploy_key';
process.env['INPUT_ENABLE_JEKYLL'] = 'true';
process.env['INPUT_DISABLE_NOJEKYLL'] = 'true';
expect(() => {
getInputs();
}).toThrow('Use either of enable_jekyll or disable_nojekyll');
});
});

View File

@ -1,302 +0,0 @@
import {
copyAssets,
setRepo,
getUserName,
getUserEmail,
setCommitAuthor,
getCommitMessage
} from '../src/git-utils';
import {getInputs} from '../src/get-inputs';
import {Inputs} from '../src/interfaces';
import {getWorkDirName, createDir} from '../src/utils';
import {CmdResult} from '../src/interfaces';
import * as exec from '@actions/exec';
import {cp, rm} from 'shelljs';
import path from 'path';
import fs from 'fs';
const testRoot = path.resolve(__dirname);
async function createTestDir(name: string): Promise<string> {
const date = new Date();
const unixTime = date.getTime();
return await getWorkDirName(`${unixTime}_${name}`);
}
beforeEach(() => {
jest.resetModules();
process.env['GITHUB_ACTOR'] = 'default-octocat';
process.env['GITHUB_REPOSITORY'] = 'owner/repo';
});
afterEach(() => {
delete process.env['GITHUB_ACTOR'];
delete process.env['GITHUB_REPOSITORY'];
});
describe('copyAssets', () => {
let gitTempDir = '';
(async (): Promise<void> => {
const date = new Date();
const unixTime = date.getTime();
gitTempDir = await getWorkDirName(`${unixTime}_git`);
})();
beforeAll(async () => {
await createDir(gitTempDir);
process.chdir(gitTempDir);
await exec.exec('git', ['init']);
});
test('copy assets from publish_dir to root, delete .github', async () => {
const publishDir = await createTestDir('src');
const destDir = await createTestDir('dst');
cp('-Rf', path.resolve(testRoot, 'fixtures/publish_dir_1'), publishDir);
cp('-Rf', gitTempDir, destDir);
await copyAssets(publishDir, destDir, '.github');
expect(fs.existsSync(path.resolve(destDir, '.github'))).toBeFalsy();
expect(fs.existsSync(path.resolve(destDir, 'index.html'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.css'))).toBeTruthy();
rm('-rf', publishDir, destDir);
});
test('copy assets from publish_dir to root, delete .github,main.js', async () => {
const publishDir = await createTestDir('src');
const destDir = await createTestDir('dst');
cp('-Rf', path.resolve(testRoot, 'fixtures/publish_dir_1'), publishDir);
cp('-Rf', gitTempDir, destDir);
await copyAssets(publishDir, destDir, '.github,main.js');
expect(fs.existsSync(path.resolve(destDir, '.github'))).toBeFalsy();
expect(fs.existsSync(path.resolve(destDir, 'index.html'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'main.js'))).toBeFalsy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.css'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.js'))).toBeTruthy();
rm('-rf', publishDir, destDir);
});
test('copy assets from publish_dir to root, delete nothing', async () => {
const publishDir = await createTestDir('src');
const destDir = await createTestDir('dst');
cp('-Rf', path.resolve(testRoot, 'fixtures/publish_dir_root'), publishDir);
cp('-Rf', gitTempDir, destDir);
await copyAssets(publishDir, destDir, '');
expect(fs.existsSync(path.resolve(destDir, '.github'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'index.html'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'main.js'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.css'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.js'))).toBeTruthy();
rm('-rf', publishDir, destDir);
});
test('copy assets from root to root, delete .github', async () => {
const publishDir = await createTestDir('src');
const destDir = await createTestDir('dst');
cp('-Rf', path.resolve(testRoot, 'fixtures/publish_dir_root'), publishDir);
cp('-Rf', gitTempDir, destDir);
cp('-Rf', gitTempDir, publishDir);
await copyAssets(publishDir, destDir, '.github');
expect(fs.existsSync(path.resolve(destDir, '.github'))).toBeFalsy();
expect(fs.existsSync(path.resolve(destDir, 'index.html'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.css'))).toBeTruthy();
rm('-rf', publishDir, destDir);
});
test('copy assets from root to root, delete nothing', async () => {
const publishDir = await createTestDir('src');
const destDir = await createTestDir('dst');
cp('-Rf', path.resolve(testRoot, 'fixtures/publish_dir_root'), publishDir);
cp('-Rf', gitTempDir, destDir);
cp('-Rf', gitTempDir, publishDir);
await copyAssets(publishDir, destDir, '');
expect(fs.existsSync(path.resolve(destDir, '.github'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'index.html'))).toBeTruthy();
expect(fs.existsSync(path.resolve(destDir, 'assets/lib.css'))).toBeTruthy();
rm('-rf', publishDir, destDir);
});
test.todo('copy assets from root to subdir, delete .github');
test.todo('copy assets from root to subdir, delete .github,main.js');
test.todo('copy assets from root to subdir, delete nothing');
});
describe('setRepo()', () => {
test('throw error destination_dir should be a relative path', async () => {
process.env['INPUT_GITHUB_TOKEN'] = 'test_github_token';
process.env['INPUT_PUBLISH_BRANCH'] = 'gh-pages';
process.env['INPUT_PUBLISH_DIR'] = 'public';
process.env['INPUT_DESTINATION_DIR'] = '/subdir';
// process.env['INPUT_EXTERNAL_REPOSITORY'] = 'user/repo';
// process.env['INPUT_ALLOW_EMPTY_COMMIT'] = 'true';
// process.env['INPUT_KEEP_FILES'] = 'true';
// process.env['INPUT_FORCE_ORPHAN'] = 'true';
// process.env['INPUT_USER_NAME'] = 'username';
// process.env['INPUT_USER_EMAIL'] = 'github@github.com';
// process.env['INPUT_COMMIT_MESSAGE'] = 'feat: Add new feature';
// process.env['INPUT_FULL_COMMIT_MESSAGE'] = 'feat: Add new feature';
// process.env['INPUT_TAG_NAME'] = 'deploy-v1.2.3';
// process.env['INPUT_TAG_MESSAGE'] = 'Deployment v1.2.3';
// process.env['INPUT_DISABLE_NOJEKYLL'] = 'true';
// process.env['INPUT_CNAME'] = 'github.com';
process.env['INPUT_EXCLUDE_ASSETS'] = '.github';
const inps: Inputs = getInputs();
const remoteURL = 'https://x-access-token:pat@github.com/actions/pages.git';
const date = new Date();
const unixTime = date.getTime();
const workDir = await getWorkDirName(`${unixTime}`);
await expect(setRepo(inps, remoteURL, workDir)).rejects.toThrow(
'destination_dir should be a relative path'
);
});
});
describe('getUserName()', () => {
test('get default git user name', () => {
const userName = '';
const test = getUserName(userName);
expect(test).toMatch('default-octocat');
});
test('get custom git user name', () => {
const userName = 'custom-octocat';
const test = getUserName(userName);
expect(test).toMatch(userName);
});
});
describe('getUserEmail()', () => {
test('get default git user email', () => {
const userEmail = '';
const test = getUserEmail(userEmail);
expect(test).toMatch('default-octocat@users.noreply.github.com');
});
test('get custom git user email', () => {
const userEmail = 'custom-octocat@github.com';
const test = getUserEmail(userEmail);
expect(test).toMatch(userEmail);
});
});
describe('setCommitAuthor()', () => {
let workDirName = '';
(async (): Promise<void> => {
const date = new Date();
const unixTime = date.getTime();
workDirName = await getWorkDirName(`${unixTime}`);
})();
beforeEach(async () => {
await createDir(workDirName);
process.chdir(workDirName);
await exec.exec('git', ['init']);
});
test('get default commit author', async () => {
const userName = '';
const userEmail = '';
const result: CmdResult = {
exitcode: 0,
output: ''
};
const options = {
listeners: {
stdout: (data: Buffer): void => {
result.output += data.toString();
}
}
};
await setCommitAuthor(userName, userEmail);
result.exitcode = await exec.exec('git', ['config', 'user.name'], options);
expect(result.output).toMatch('default-octocat');
result.exitcode = await exec.exec('git', ['config', 'user.email'], options);
expect(result.output).toMatch('default-octocat@users.noreply.github.com');
});
test('get custom commit author', async () => {
const userName = 'custom-octocat';
const userEmail = 'custom-octocat@github.com';
const result: CmdResult = {
exitcode: 0,
output: ''
};
const options = {
listeners: {
stdout: (data: Buffer): void => {
result.output += data.toString();
}
}
};
await setCommitAuthor(userName, userEmail);
result.exitcode = await exec.exec('git', ['config', 'user.name'], options);
expect(result.output).toMatch(userName);
result.exitcode = await exec.exec('git', ['config', 'user.email'], options);
expect(result.output).toMatch(userEmail);
});
test('throw error user_email is undefined', async () => {
const userName = 'custom-octocat';
const userEmail = '';
await expect(setCommitAuthor(userName, userEmail)).rejects.toThrow('user_email is undefined');
});
test('throw error user_name is undefined', async () => {
const userName = '';
const userEmail = 'custom-octocat@github.com';
await expect(setCommitAuthor(userName, userEmail)).rejects.toThrow('user_name is undefined');
});
});
describe('getCommitMessage()', () => {
test('get default message', () => {
const test = getCommitMessage('', '', '', 'actions/pages', 'commit_hash');
expect(test).toMatch('deploy: commit_hash');
});
test('get default message for external repository', () => {
const test = getCommitMessage(
'',
'',
'actions/actions.github.io',
'actions/pages',
'commit_hash'
);
expect(test).toMatch('deploy: actions/pages@commit_hash');
});
test('get custom message', () => {
const test = getCommitMessage('Custom msg', '', '', 'actions/pages', 'commit_hash');
expect(test).toMatch('Custom msg commit_hash');
});
test('get custom message for external repository', () => {
const test = getCommitMessage(
'Custom msg',
'',
'actions/actions.github.io',
'actions/pages',
'commit_hash'
);
expect(test).toMatch('Custom msg actions/pages@commit_hash');
});
test('get full custom message', () => {
const test = getCommitMessage('', 'Full custom msg', '', 'actions/pages', 'commit_hash');
expect(test).toMatch('Full custom msg');
});
test('get full custom message for external repository', () => {
const test = getCommitMessage(
'',
'Full custom msg',
'actions/actions.github.io',
'actions/pages',
'commit_hash'
);
expect(test).toMatch('Full custom msg');
});
});

View File

@ -1,37 +0,0 @@
import {setPersonalToken, setGithubToken} from '../src/set-tokens';
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules();
process.env = {...OLD_ENV};
});
afterAll(() => {
process.env = OLD_ENV; // Restore old environment
});
describe('setGithubToken()', () => {
test('return remote url with GITHUB_TOKEN gh-pages', () => {
process.env.GITHUB_SERVER_URL = 'https://github.enterprise.server';
const expected = 'https://x-access-token:GITHUB_TOKEN@github.enterprise.server/owner/repo.git';
const test = setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages',
'',
'refs/heads/master',
'push'
);
expect(test).toMatch(expected);
});
});
describe('setPersonalToken()', () => {
test('return remote url with personal access token', () => {
process.env.GITHUB_SERVER_URL = 'https://github.enterprise.server';
const expected = 'https://x-access-token:pat@github.enterprise.server/owner/repo.git';
const test = setPersonalToken('pat', 'owner/repo');
expect(test).toMatch(expected);
});
});

View File

@ -1,118 +0,0 @@
import {getPublishRepo, setPersonalToken, setGithubToken} from '../src/set-tokens';
beforeEach(() => {
jest.resetModules();
});
// afterEach(() => {
// });
describe('getPublishRepo()', () => {
test('return repository name', () => {
const test = getPublishRepo('', 'owner', 'repo');
expect(test).toMatch('owner/repo');
});
test('return external repository name', () => {
const test = getPublishRepo('extOwner/extRepo', 'owner', 'repo');
expect(test).toMatch('extOwner/extRepo');
});
});
describe('setGithubToken()', () => {
test('return remote url with GITHUB_TOKEN gh-pages', () => {
const expected = 'https://x-access-token:GITHUB_TOKEN@github.com/owner/repo.git';
const test = setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages',
'',
'refs/heads/master',
'push'
);
expect(test).toMatch(expected);
});
test('return remote url with GITHUB_TOKEN master', () => {
const expected = 'https://x-access-token:GITHUB_TOKEN@github.com/owner/repo.git';
const test = setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'master',
'',
'refs/heads/source',
'push'
);
expect(test).toMatch(expected);
});
test('return remote url with GITHUB_TOKEN gh-pages (RegExp)', () => {
const expected = 'https://x-access-token:GITHUB_TOKEN@github.com/owner/repo.git';
const test = setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages',
'',
'refs/heads/gh-pages-base',
'push'
);
expect(test).toMatch(expected);
});
test('throw error gh-pages-base to gh-pages-base (RegExp)', () => {
expect(() => {
setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages-base',
'',
'refs/heads/gh-pages-base',
'push'
);
}).toThrow('You deploy from gh-pages-base to gh-pages-base');
});
test('throw error master to master', () => {
expect(() => {
setGithubToken('GITHUB_TOKEN', 'owner/repo', 'master', '', 'refs/heads/master', 'push');
}).toThrow('You deploy from master to master');
});
test('throw error external repository with GITHUB_TOKEN', () => {
expect(() => {
setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages',
'extOwner/extRepo',
'refs/heads/master',
'push'
);
}).toThrow(`\
The generated GITHUB_TOKEN (github_token) does not support to push to an external repository.
Use deploy_key or personal_token.
`);
});
test('return remote url with GITHUB_TOKEN pull_request', () => {
const expected = 'https://x-access-token:GITHUB_TOKEN@github.com/owner/repo.git';
const test = setGithubToken(
'GITHUB_TOKEN',
'owner/repo',
'gh-pages',
'',
'refs/pull/29/merge',
'pull_request'
);
expect(test).toMatch(expected);
});
});
describe('setPersonalToken()', () => {
test('return remote url with personal access token', () => {
const expected = 'https://x-access-token:pat@github.com/owner/repo.git';
const test = setPersonalToken('pat', 'owner/repo');
expect(test).toMatch(expected);
});
});

View File

@ -1,183 +0,0 @@
import path from 'path';
import fs from 'fs';
import {
getHomeDir,
getWorkDirName,
createDir,
addNoJekyll,
addCNAME,
skipOnFork
} from '../src/utils';
beforeEach(() => {
jest.resetModules();
});
// afterEach(() => {
// });
async function getTime(): Promise<string> {
const date = new Date();
const unixTime = date.getTime();
return `${unixTime}`;
}
describe('getHomeDir()', () => {
test('get home directory name', async () => {
let test = '';
if (process.platform === 'win32') {
test = 'C:\\Users\\runneradmin';
} else {
test = `${process.env.HOME}`;
}
const expected = await getHomeDir();
expect(test).toMatch(expected);
});
});
describe('getWorkDirName()', () => {
test('get work directory name', async () => {
let home = '';
if (process.platform === 'win32') {
home = 'C:\\Users\\runneradmin';
} else {
home = `${process.env.HOME}`;
}
const unixTime = await getTime();
const expected = path.join(home, `actions_github_pages_${unixTime}`);
const test = await getWorkDirName(`${unixTime}`);
expect(test).toMatch(expected);
});
});
describe('createDir()', () => {
test('create a directory', async () => {
const unixTime = await getTime();
const workDirName = await getWorkDirName(`${unixTime}`);
await createDir(workDirName);
const test = fs.existsSync(workDirName);
expect(test).toBe(true);
});
});
async function getWorkDir(): Promise<string> {
const unixTime = await getTime();
let workDir = '';
workDir = await getWorkDirName(`${unixTime}`);
await createDir(workDir);
return workDir;
}
describe('addNoJekyll()', () => {
test('add .nojekyll', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, '.nojekyll');
await addNoJekyll(workDir, false);
const test = fs.existsSync(filepath);
expect(test).toBe(true);
fs.unlinkSync(filepath);
});
test('.nojekyll already exists', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, '.nojekyll');
fs.closeSync(fs.openSync(filepath, 'w'));
await addNoJekyll(workDir, false);
const test = fs.existsSync(filepath);
expect(test).toBe(true);
fs.unlinkSync(filepath);
});
test('not add .nojekyll disable_nojekyll', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, '.nojekyll');
await addNoJekyll(workDir, true);
const test = fs.existsSync(filepath);
expect(test).toBe(false);
});
});
describe('addCNAME()', () => {
test('add CNAME', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, 'CNAME');
await addCNAME(workDir, 'github.com');
const test = fs.readFileSync(filepath, 'utf8');
expect(test).toMatch('github.com');
fs.unlinkSync(filepath);
});
test('do nothing', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, 'CNAME');
await addCNAME(workDir, '');
const test = fs.existsSync(filepath);
expect(test).toBe(false);
});
test('CNAME already exists', async () => {
let workDir = '';
(async (): Promise<void> => {
workDir = await getWorkDir();
})();
const filepath = path.join(workDir, 'CNAME');
await addCNAME(workDir, 'github.io');
await addCNAME(workDir, 'github.com');
const test = fs.readFileSync(filepath, 'utf8');
expect(test).toMatch('github.io');
fs.unlinkSync(filepath);
});
});
describe('skipOnFork()', () => {
test('return false on upstream', async () => {
const test = await skipOnFork(false, 'token', '', '');
expect(test).toBeFalsy();
});
test('return false on fork with github_token', async () => {
const test = await skipOnFork(true, 'token', '', '');
expect(test).toBeFalsy();
});
test('return false on fork with deploy_key', async () => {
const test = await skipOnFork(true, '', 'deploy_key', '');
expect(test).toBeFalsy();
});
test('return false on fork with personal_token', async () => {
const test = await skipOnFork(true, '', '', 'personal_token');
expect(test).toBeFalsy();
});
test('return true on fork with no tokens', async () => {
const test = await skipOnFork(true, '', '', '');
expect(test).toBeTruthy();
});
});

View File

@ -1,79 +1,9 @@
name: 'GitHub Pages action'
description: 'GitHub Actions for GitHub Pages 🚀 Deploy static files and publish your site easily. Static-Site-Generators-friendly.'
name: 'Deploy action for GitHub Pages'
description: 'A GitHub Action to deploy your static site to GitHub Pages with Static Site Generator'
author: 'peaceiris'
runs:
using: 'node20'
main: 'lib/index.js'
using: 'docker'
image: 'Dockerfile'
branding:
icon: 'upload-cloud'
color: 'blue'
inputs:
deploy_key:
description: 'Set a SSH private key from repository secret value for pushing to the remote branch.'
required: false
github_token:
description: 'Set a generated GITHUB_TOKEN for pushing to the remote branch.'
required: false
personal_token:
description: 'Set a personal access token for pushing to the remote branch.'
required: false
publish_branch:
description: 'Set a target branch for deployment.'
required: false
default: 'gh-pages'
publish_dir:
description: 'Set an input directory for deployment.'
required: false
default: 'public'
destination_dir:
description: 'Set an destination subdirectory for deployment.'
required: false
default: ''
external_repository:
description: 'Set an external repository (owner/repo).'
required: false
allow_empty_commit:
description: 'If empty commits should be made to the publication branch'
required: false
default: 'false'
keep_files:
description: 'If existing files in the publish branch should be not removed before deploying'
required: false
default: 'false'
force_orphan:
description: 'Keep only the latest commit on a GitHub Pages branch'
required: false
default: 'false'
user_name:
description: 'Set Git user.name'
required: false
user_email:
description: 'Set Git user.email'
required: false
commit_message:
description: 'Set a custom commit message with a triggered commit hash'
required: false
full_commit_message:
description: 'Set a custom full commit message without a triggered commit hash'
required: false
tag_name:
description: 'Set tag name'
required: false
tag_message:
description: 'Set tag message'
required: false
enable_jekyll:
description: 'Enable the GitHub Pages built-in Jekyll'
required: false
default: 'false'
disable_nojekyll:
description: 'An alias for enable_jekyll to disable adding .nojekyll file to a publishing branch'
required: false
default: 'false'
cname:
description: 'Set custom domain'
required: false
exclude_assets:
description: 'Set files or directories to exclude from a publish directory.'
required: false
default: '.github'

70
entrypoint.sh Executable file
View File

@ -0,0 +1,70 @@
#!/bin/bash
set -e
# set -ex
function print_error() {
echo -e "\e[31mERROR: ${1}\e[m"
}
function print_info() {
echo -e "\e[36mINFO: ${1}\e[m"
}
# check values
if [ -n "${ACTIONS_DEPLOY_KEY}" ]; then
print_info "setup with ACTIONS_DEPLOY_KEY"
mkdir /root/.ssh
ssh-keyscan -t rsa github.com > /root/.ssh/known_hosts
echo "${ACTIONS_DEPLOY_KEY}" > /root/.ssh/id_rsa
chmod 400 /root/.ssh/id_rsa
remote_repo="git@github.com:${GITHUB_REPOSITORY}.git"
elif [ -n "${GITHUB_TOKEN}" ]; then
print_info "setup with GITHUB_TOKEN"
remote_repo="https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
else
print_error "not found ACTIONS_DEPLOY_KEY or GITHUB_TOKEN"
exit 1
fi
if [ -z "${PUBLISH_BRANCH}" ]; then
print_error "not found PUBLISH_BRANCH"
exit 1
fi
if [ -z "${PUBLISH_DIR}" ]; then
print_error "not found PUBLISH_DIR"
exit 1
fi
remote_branch="${PUBLISH_BRANCH}"
local_dir="${HOME}/$(tr -cd 'a-f0-9' < /dev/urandom | head -c 32)"
if git clone --depth=1 --single-branch --branch "${remote_branch}" "${remote_repo}" "${local_dir}"; then
cd "${local_dir}"
git rm -r '*'
find "${GITHUB_WORKSPACE}/${PUBLISH_DIR}" -maxdepth 1 | \
tail -n +2 | \
xargs -I % cp -rf % "${local_dir}/"
else
cd "${PUBLISH_DIR}"
git init
git checkout --orphan "${remote_branch}"
fi
# push to publishing branch
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git remote rm origin || true
git remote add origin "${remote_repo}"
git add --all
git commit --allow-empty -m "Automated deployment: $(date -u) ${GITHUB_SHA}"
git push origin "${remote_branch}"
print_info "${GITHUB_SHA} was successfully deployed"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

View File

@ -1,11 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
};

13628
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +0,0 @@
{
"name": "actions-github-pages",
"version": "4.0.0",
"description": "GitHub Actions for GitHub Pages",
"main": "lib/index.js",
"engines": {
"node": ">=v20.11.0",
"npm": ">=10.2.4"
},
"scripts": {
"postinstall": "npx husky install",
"all": "npm run format && npm run lint && npm test",
"lint": "eslint ./{src,__tests__}/**/*.ts",
"lint:fix": "eslint --fix ./{src,__tests__}/**/*.ts",
"test": "jest --coverage --verbose --detectOpenHandles",
"build": "ncc build ./src/index.ts -o lib --minify",
"tsc": "tsc",
"format": "prettier --write '**/*.ts'",
"format:check": "prettier --check '**/*.ts'",
"release": "standard-version"
},
"lint-staged": {
"{src,__tests__}/**/*.ts": [
"prettier --check",
"eslint"
],
"README.md": [
"npx doctoc@2.1.0 --github"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/peaceiris/actions-gh-pages.git"
},
"keywords": [
"GitHub Actions",
"Actions",
"JavaScript Action",
"TypeScript Action",
"GitHub Pages",
"gh-pages"
],
"author": "peaceiris",
"license": "MIT",
"bugs": {
"url": "https://github.com/peaceiris/actions-gh-pages/issues"
},
"homepage": "https://github.com/peaceiris/actions-gh-pages#readme",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1",
"@actions/glob": "^0.5.0",
"@actions/io": "^1.1.2",
"@types/shelljs": "^0.8.11",
"shelljs": "^0.8.5"
},
"devDependencies": {
"@types/jest": "^29.2.6",
"@types/js-yaml": "^4.0.5",
"@types/node": "~16",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"@typescript-eslint/parser": "^5.48.2",
"@vercel/ncc": "^0.38.0",
"eslint": "^8.32.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-prettier": "^4.2.1",
"husky": "^8.0.3",
"jest": "^29.3.1",
"jest-circus": "^29.3.1",
"js-yaml": "^4.1.0",
"lint-staged": "^13.1.0",
"prettier": "2.8.8",
"standard-version": "^9.1.1",
"ts-jest": "^29.0.5",
"typescript": "^4.9.4"
}
}

View File

@ -1,70 +0,0 @@
#!/usr/bin/env bash
# fail on unset variables and command errors
set -eu -o pipefail # -x: is for debugging
DEFAULT_BRANCH="main"
CURRENT_BRANCH="$(git branch --show-current)"
if [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then
echo "$0: Current branch ${CURRENT_BRANCH} is not ${DEFAULT_BRANCH}, continue? (y/n)"
read -r res
if [ "${res}" = "n" ]; then
echo "$0: Stop script"
exit 0
fi
fi
PRERELEASE_TYPE_LIST="prerelease prepatch preminor premajor"
if [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then
RELEASE_TYPE_LIST="${PRERELEASE_TYPE_LIST}"
else
RELEASE_TYPE_LIST="${PRERELEASE_TYPE_LIST} patch minor major"
fi
if command -v fzf; then
RELEASE_TYPE=$(echo "${RELEASE_TYPE_LIST}" | tr ' ' '\n' | fzf --layout=reverse)
else
select sel in ${RELEASE_TYPE_LIST}; do
RELEASE_TYPE="${sel}"
break
done
fi
echo "$0: Create ${RELEASE_TYPE} release, continue? (y/n)"
read -r res
if [ "${res}" = "n" ]; then
echo "$0: Stop script"
exit 0
fi
git fetch origin
if [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then
git pull origin "${CURRENT_BRANCH}"
else
git pull origin ${DEFAULT_BRANCH}
git tag -d v3 || true
git pull origin --tags
fi
npm install
mkdir ./lib
npm run build
git add ./lib/index.js
git commit -m "chore(release): Add build assets"
npm run release -- --release-as "${RELEASE_TYPE}" --preset eslint
git rm ./lib/index.js
rm -rf ./lib
git commit -m "chore(release): Remove build assets [skip ci]"
if [ "${CURRENT_BRANCH}" != "${DEFAULT_BRANCH}" ]; then
git push origin "${CURRENT_BRANCH}"
else
git push origin ${DEFAULT_BRANCH}
fi
TAG_NAME="v$(jq -r '.version' ./package.json)"
git push origin "${TAG_NAME}"

View File

@ -1,13 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>peaceiris/renovate-config"
],
"packageRules": [
{
"automerge": false,
"matchUpdateTypes": ["minor", "patch"],
"automergeStrategy": "squash"
}
]
}

View File

@ -1,74 +0,0 @@
import * as core from '@actions/core';
import {Inputs} from './interfaces';
export function showInputs(inps: Inputs): void {
let authMethod = '';
if (inps.DeployKey) {
authMethod = 'DeployKey';
} else if (inps.GithubToken) {
authMethod = 'GithubToken';
} else if (inps.PersonalToken) {
authMethod = 'PersonalToken';
}
core.info(`\
[INFO] ${authMethod}: true
[INFO] PublishBranch: ${inps.PublishBranch}
[INFO] PublishDir: ${inps.PublishDir}
[INFO] DestinationDir: ${inps.DestinationDir}
[INFO] ExternalRepository: ${inps.ExternalRepository}
[INFO] AllowEmptyCommit: ${inps.AllowEmptyCommit}
[INFO] KeepFiles: ${inps.KeepFiles}
[INFO] ForceOrphan: ${inps.ForceOrphan}
[INFO] UserName: ${inps.UserName}
[INFO] UserEmail: ${inps.UserEmail}
[INFO] CommitMessage: ${inps.CommitMessage}
[INFO] FullCommitMessage: ${inps.FullCommitMessage}
[INFO] TagName: ${inps.TagName}
[INFO] TagMessage: ${inps.TagMessage}
[INFO] EnableJekyll (DisableNoJekyll): ${inps.DisableNoJekyll}
[INFO] CNAME: ${inps.CNAME}
[INFO] ExcludeAssets ${inps.ExcludeAssets}
`);
}
export function getInputs(): Inputs {
let useBuiltinJekyll = false;
const isBoolean = (param: string): boolean => (param || 'false').toUpperCase() === 'TRUE';
const enableJekyll: boolean = isBoolean(core.getInput('enable_jekyll'));
const disableNoJekyll: boolean = isBoolean(core.getInput('disable_nojekyll'));
if (enableJekyll && disableNoJekyll) {
throw new Error(`Use either of enable_jekyll or disable_nojekyll`);
} else if (enableJekyll) {
useBuiltinJekyll = true;
} else if (disableNoJekyll) {
useBuiltinJekyll = true;
}
const inps: Inputs = {
DeployKey: core.getInput('deploy_key'),
GithubToken: core.getInput('github_token'),
PersonalToken: core.getInput('personal_token'),
PublishBranch: core.getInput('publish_branch'),
PublishDir: core.getInput('publish_dir'),
DestinationDir: core.getInput('destination_dir'),
ExternalRepository: core.getInput('external_repository'),
AllowEmptyCommit: isBoolean(core.getInput('allow_empty_commit')),
KeepFiles: isBoolean(core.getInput('keep_files')),
ForceOrphan: isBoolean(core.getInput('force_orphan')),
UserName: core.getInput('user_name'),
UserEmail: core.getInput('user_email'),
CommitMessage: core.getInput('commit_message'),
FullCommitMessage: core.getInput('full_commit_message'),
TagName: core.getInput('tag_name'),
TagMessage: core.getInput('tag_message'),
DisableNoJekyll: useBuiltinJekyll,
CNAME: core.getInput('cname'),
ExcludeAssets: core.getInput('exclude_assets')
};
return inps;
}

View File

@ -1,240 +0,0 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as glob from '@actions/glob';
import path from 'path';
import fs from 'fs';
import {URL} from 'url';
import {Inputs, CmdResult} from './interfaces';
import {createDir} from './utils';
import {cp, rm} from 'shelljs';
export async function createBranchForce(branch: string): Promise<void> {
await exec.exec('git', ['init']);
await exec.exec('git', ['checkout', '--orphan', branch]);
return;
}
export function getServerUrl(): URL {
return new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
}
export async function deleteExcludedAssets(destDir: string, excludeAssets: string): Promise<void> {
if (excludeAssets === '') return;
core.info(`[INFO] delete excluded assets`);
const excludedAssetNames: Array<string> = excludeAssets.split(',');
const excludedAssetPaths = ((): Array<string> => {
const paths: Array<string> = [];
for (const pattern of excludedAssetNames) {
paths.push(path.join(destDir, pattern));
}
return paths;
})();
const globber = await glob.create(excludedAssetPaths.join('\n'));
const files = await globber.glob();
for await (const file of globber.globGenerator()) {
core.info(`[INFO] delete ${file}`);
}
rm('-rf', files);
return;
}
export async function copyAssets(
publishDir: string,
destDir: string,
excludeAssets: string
): Promise<void> {
core.info(`[INFO] prepare publishing assets`);
if (!fs.existsSync(destDir)) {
core.info(`[INFO] create ${destDir}`);
await createDir(destDir);
}
const dotGitPath = path.join(publishDir, '.git');
if (fs.existsSync(dotGitPath)) {
core.info(`[INFO] delete ${dotGitPath}`);
rm('-rf', dotGitPath);
}
core.info(`[INFO] copy ${publishDir} to ${destDir}`);
cp('-RfL', [`${publishDir}/*`, `${publishDir}/.*`], destDir);
await deleteExcludedAssets(destDir, excludeAssets);
return;
}
export async function setRepo(inps: Inputs, remoteURL: string, workDir: string): Promise<void> {
const publishDir = path.isAbsolute(inps.PublishDir)
? inps.PublishDir
: path.join(`${process.env.GITHUB_WORKSPACE}`, inps.PublishDir);
if (path.isAbsolute(inps.DestinationDir)) {
throw new Error('destination_dir should be a relative path');
}
const destDir = ((): string => {
if (inps.DestinationDir === '') {
return workDir;
} else {
return path.join(workDir, inps.DestinationDir);
}
})();
core.info(`[INFO] ForceOrphan: ${inps.ForceOrphan}`);
if (inps.ForceOrphan) {
await createDir(destDir);
core.info(`[INFO] chdir ${workDir}`);
process.chdir(workDir);
await createBranchForce(inps.PublishBranch);
await copyAssets(publishDir, destDir, inps.ExcludeAssets);
return;
}
const result: CmdResult = {
exitcode: 0,
output: ''
};
const options = {
listeners: {
stdout: (data: Buffer): void => {
result.output += data.toString();
}
}
};
try {
result.exitcode = await exec.exec(
'git',
['clone', '--depth=1', '--single-branch', '--branch', inps.PublishBranch, remoteURL, workDir],
options
);
if (result.exitcode === 0) {
await createDir(destDir);
if (inps.KeepFiles) {
core.info('[INFO] Keep existing files');
} else {
core.info(`[INFO] clean up ${destDir}`);
core.info(`[INFO] chdir ${destDir}`);
process.chdir(destDir);
await exec.exec('git', ['rm', '-r', '--ignore-unmatch', '*']);
}
core.info(`[INFO] chdir ${workDir}`);
process.chdir(workDir);
await copyAssets(publishDir, destDir, inps.ExcludeAssets);
return;
} else {
throw new Error(`Failed to clone remote branch ${inps.PublishBranch}`);
}
} catch (error) {
if (error instanceof Error) {
core.info(`[INFO] first deployment, create new branch ${inps.PublishBranch}`);
core.info(`[INFO] ${error.message}`);
await createDir(destDir);
core.info(`[INFO] chdir ${workDir}`);
process.chdir(workDir);
await createBranchForce(inps.PublishBranch);
await copyAssets(publishDir, destDir, inps.ExcludeAssets);
return;
} else {
throw new Error('unexpected error');
}
}
}
export function getUserName(userName: string): string {
if (userName) {
return userName;
} else {
return `${process.env.GITHUB_ACTOR}`;
}
}
export function getUserEmail(userEmail: string): string {
if (userEmail) {
return userEmail;
} else {
return `${process.env.GITHUB_ACTOR}@users.noreply.github.com`;
}
}
export async function setCommitAuthor(userName: string, userEmail: string): Promise<void> {
if (userName && !userEmail) {
throw new Error('user_email is undefined');
}
if (!userName && userEmail) {
throw new Error('user_name is undefined');
}
await exec.exec('git', ['config', 'user.name', getUserName(userName)]);
await exec.exec('git', ['config', 'user.email', getUserEmail(userEmail)]);
}
export function getCommitMessage(
msg: string,
fullMsg: string,
extRepo: string,
baseRepo: string,
hash: string
): string {
const msgHash = ((): string => {
if (extRepo) {
return `${baseRepo}@${hash}`;
} else {
return hash;
}
})();
const subject = ((): string => {
if (fullMsg) {
return fullMsg;
} else if (msg) {
return `${msg} ${msgHash}`;
} else {
return `deploy: ${msgHash}`;
}
})();
return subject;
}
export async function commit(allowEmptyCommit: boolean, msg: string): Promise<void> {
try {
if (allowEmptyCommit) {
await exec.exec('git', ['commit', '--allow-empty', '-m', `${msg}`]);
} else {
await exec.exec('git', ['commit', '-m', `${msg}`]);
}
} catch (error) {
if (error instanceof Error) {
core.info('[INFO] skip commit');
core.debug(`[INFO] skip commit ${error.message}`);
} else {
throw new Error('unexpected error');
}
}
}
export async function push(branch: string, forceOrphan: boolean): Promise<void> {
if (forceOrphan) {
await exec.exec('git', ['push', 'origin', '--force', branch]);
} else {
await exec.exec('git', ['push', 'origin', branch]);
}
}
export async function pushTag(tagName: string, tagMessage: string): Promise<void> {
if (tagName === '') {
return;
}
let msg = '';
if (tagMessage) {
msg = tagMessage;
} else {
msg = `Deployment ${tagName}`;
}
await exec.exec('git', ['tag', '-a', `${tagName}`, '-m', `${msg}`]);
await exec.exec('git', ['push', 'origin', `${tagName}`]);
}

View File

@ -1,14 +0,0 @@
import * as core from '@actions/core';
import * as main from './main';
(async (): Promise<void> => {
try {
await main.run();
} catch (error) {
if (error instanceof Error) {
core.setFailed(`Action failed with "${error.message}"`);
} else {
core.setFailed('unexpected error');
}
}
})();

View File

@ -1,26 +0,0 @@
export interface Inputs {
readonly DeployKey: string;
readonly GithubToken: string;
readonly PersonalToken: string;
readonly PublishBranch: string;
readonly PublishDir: string;
readonly DestinationDir: string;
readonly ExternalRepository: string;
readonly AllowEmptyCommit: boolean;
readonly KeepFiles: boolean;
readonly ForceOrphan: boolean;
readonly UserName: string;
readonly UserEmail: string;
readonly CommitMessage: string;
readonly FullCommitMessage: string;
readonly TagName: string;
readonly TagMessage: string;
readonly DisableNoJekyll: boolean;
readonly CNAME: string;
readonly ExcludeAssets: string;
}
export interface CmdResult {
exitcode: number;
output: string;
}

View File

@ -1,100 +0,0 @@
import {context} from '@actions/github';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as github from '@actions/github';
import {Inputs} from './interfaces';
import {showInputs, getInputs} from './get-inputs';
import {setTokens} from './set-tokens';
import {setRepo, setCommitAuthor, getCommitMessage, commit, push, pushTag} from './git-utils';
import {getWorkDirName, addNoJekyll, addCNAME, skipOnFork} from './utils';
export async function run(): Promise<void> {
try {
core.info('[INFO] Usage https://github.com/peaceiris/actions-gh-pages#readme');
const inps: Inputs = getInputs();
core.startGroup('Dump inputs');
showInputs(inps);
core.endGroup();
if (core.isDebug()) {
core.startGroup('Debug: dump context');
console.log(context);
core.endGroup();
}
const eventName = context.eventName;
if (eventName === 'pull_request' || eventName === 'push') {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isForkRepository = (context.payload as any).repository.fork;
const isSkipOnFork = await skipOnFork(
isForkRepository,
inps.GithubToken,
inps.DeployKey,
inps.PersonalToken
);
if (isSkipOnFork) {
core.warning('This action runs on a fork and not found auth token, Skip deployment');
core.setOutput('skip', 'true');
return;
}
}
core.startGroup('Setup auth token');
const remoteURL = await setTokens(inps);
core.debug(`remoteURL: ${remoteURL}`);
core.endGroup();
core.startGroup('Prepare publishing assets');
const date = new Date();
const unixTime = date.getTime();
const workDir = await getWorkDirName(`${unixTime}`);
await setRepo(inps, remoteURL, workDir);
await addNoJekyll(workDir, inps.DisableNoJekyll);
await addCNAME(workDir, inps.CNAME);
core.endGroup();
core.startGroup('Setup Git config');
try {
await exec.exec('git', ['remote', 'rm', 'origin']);
} catch (error) {
if (error instanceof Error) {
core.info(`[INFO] ${error.message}`);
} else {
throw new Error('unexpected error');
}
}
await exec.exec('git', ['remote', 'add', 'origin', remoteURL]);
await exec.exec('git', ['add', '--all']);
await setCommitAuthor(inps.UserName, inps.UserEmail);
core.endGroup();
core.startGroup('Create a commit');
const hash = `${process.env.GITHUB_SHA}`;
const baseRepo = `${github.context.repo.owner}/${github.context.repo.repo}`;
const commitMessage = getCommitMessage(
inps.CommitMessage,
inps.FullCommitMessage,
inps.ExternalRepository,
baseRepo,
hash
);
await commit(inps.AllowEmptyCommit, commitMessage);
core.endGroup();
core.startGroup('Push the commit or tag');
await push(inps.PublishBranch, inps.ForceOrphan);
await pushTag(inps.TagName, inps.TagMessage);
core.endGroup();
core.info('[INFO] Action successfully completed');
return;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error('unexpected error');
}
}
}

View File

@ -1,148 +0,0 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as github from '@actions/github';
import * as io from '@actions/io';
import path from 'path';
import fs from 'fs';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const cpSpawnSync = require('child_process').spawnSync;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const cpexec = require('child_process').execFileSync;
import {Inputs} from './interfaces';
import {getHomeDir} from './utils';
import {getServerUrl} from './git-utils';
export async function setSSHKey(inps: Inputs, publishRepo: string): Promise<string> {
core.info('[INFO] setup SSH deploy key');
const homeDir = await getHomeDir();
const sshDir = path.join(homeDir, '.ssh');
await io.mkdirP(sshDir);
await exec.exec('chmod', ['700', sshDir]);
const knownHosts = path.join(sshDir, 'known_hosts');
// ssh-keyscan -t rsa github.com or serverUrl >> ~/.ssh/known_hosts on Ubuntu
const cmdSSHkeyscanOutput = `\
# ${getServerUrl().host}.com:22 SSH-2.0-babeld-1f0633a6
${
getServerUrl().host
} ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
`;
fs.writeFileSync(knownHosts, cmdSSHkeyscanOutput + '\n');
core.info(`[INFO] wrote ${knownHosts}`);
await exec.exec('chmod', ['600', knownHosts]);
const idRSA = path.join(sshDir, 'github');
fs.writeFileSync(idRSA, inps.DeployKey + '\n');
core.info(`[INFO] wrote ${idRSA}`);
await exec.exec('chmod', ['600', idRSA]);
const sshConfigPath = path.join(sshDir, 'config');
const sshConfigContent = `\
Host ${getServerUrl().host}
HostName ${getServerUrl().host}
IdentityFile ~/.ssh/github
User git
`;
fs.writeFileSync(sshConfigPath, sshConfigContent + '\n');
core.info(`[INFO] wrote ${sshConfigPath}`);
await exec.exec('chmod', ['600', sshConfigPath]);
if (process.platform === 'win32') {
core.warning(`\
Currently, the deploy_key option is not supported on the windows-latest.
Watch https://github.com/peaceiris/actions-gh-pages/issues/87
`);
await cpSpawnSync('Start-Process', ['powershell.exe', '-Verb', 'runas']);
await cpSpawnSync('sh', ['-c', '\'eval "$(ssh-agent)"\''], {shell: true});
await exec.exec('sc', ['config', 'ssh-agent', 'start=auto']);
await exec.exec('sc', ['start', 'ssh-agent']);
}
await cpexec('ssh-agent', ['-a', '/tmp/ssh-auth.sock']);
core.exportVariable('SSH_AUTH_SOCK', '/tmp/ssh-auth.sock');
await exec.exec('ssh-add', [idRSA]);
return `git@${getServerUrl().host}:${publishRepo}.git`;
}
export function setGithubToken(
githubToken: string,
publishRepo: string,
publishBranch: string,
externalRepository: string,
ref: string,
eventName: string
): string {
core.info('[INFO] setup GITHUB_TOKEN');
core.debug(`ref: ${ref}`);
core.debug(`eventName: ${eventName}`);
let isProhibitedBranch = false;
if (externalRepository) {
throw new Error(`\
The generated GITHUB_TOKEN (github_token) does not support to push to an external repository.
Use deploy_key or personal_token.
`);
}
if (eventName === 'push') {
isProhibitedBranch = ref.match(new RegExp(`^refs/heads/${publishBranch}$`)) !== null;
if (isProhibitedBranch) {
throw new Error(`\
You deploy from ${publishBranch} to ${publishBranch}
This operation is prohibited to protect your contents
`);
}
}
return `https://x-access-token:${githubToken}@${getServerUrl().host}/${publishRepo}.git`;
}
export function setPersonalToken(personalToken: string, publishRepo: string): string {
core.info('[INFO] setup personal access token');
return `https://x-access-token:${personalToken}@${getServerUrl().host}/${publishRepo}.git`;
}
export function getPublishRepo(externalRepository: string, owner: string, repo: string): string {
if (externalRepository) {
return externalRepository;
}
return `${owner}/${repo}`;
}
export async function setTokens(inps: Inputs): Promise<string> {
try {
const publishRepo = getPublishRepo(
inps.ExternalRepository,
github.context.repo.owner,
github.context.repo.repo
);
if (inps.DeployKey) {
return setSSHKey(inps, publishRepo);
} else if (inps.GithubToken) {
const context = github.context;
const ref = context.ref;
const eventName = context.eventName;
return setGithubToken(
inps.GithubToken,
publishRepo,
inps.PublishBranch,
inps.ExternalRepository,
ref,
eventName
);
} else if (inps.PersonalToken) {
return setPersonalToken(inps.PersonalToken, publishRepo);
} else {
throw new Error('not found deploy key or tokens');
}
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error('unexpected error');
}
}
}

View File

@ -1,70 +0,0 @@
import * as core from '@actions/core';
import * as io from '@actions/io';
import path from 'path';
import fs from 'fs';
export async function getHomeDir(): Promise<string> {
let homedir = '';
if (process.platform === 'win32') {
homedir = process.env['USERPROFILE'] || 'C:\\';
} else {
homedir = `${process.env.HOME}`;
}
core.debug(`homeDir: ${homedir}`);
return homedir;
}
export async function getWorkDirName(unixTime: string): Promise<string> {
const homeDir = await getHomeDir();
const workDirName = path.join(homeDir, `actions_github_pages_${unixTime}`);
return workDirName;
}
export async function createDir(dirPath: string): Promise<void> {
await io.mkdirP(dirPath);
core.debug(`Created directory ${dirPath}`);
return;
}
export async function addNoJekyll(workDir: string, DisableNoJekyll: boolean): Promise<void> {
if (DisableNoJekyll) {
return;
}
const filepath = path.join(workDir, '.nojekyll');
if (fs.existsSync(filepath)) {
return;
}
fs.closeSync(fs.openSync(filepath, 'w'));
core.info(`[INFO] Created ${filepath}`);
}
export async function addCNAME(workDir: string, content: string): Promise<void> {
if (content === '') {
return;
}
const filepath = path.join(workDir, 'CNAME');
if (fs.existsSync(filepath)) {
core.info(`CNAME already exists, skip adding CNAME`);
return;
}
fs.writeFileSync(filepath, content + '\n');
core.info(`[INFO] Created ${filepath}`);
}
export async function skipOnFork(
isForkRepository: boolean,
githubToken: string,
deployKey: string,
personalToken: string
): Promise<boolean> {
if (isForkRepository) {
if (githubToken === '' && deployKey === '' && personalToken === '') {
return true;
}
}
return false;
}

View File

@ -1 +0,0 @@
book

View File

@ -1,6 +0,0 @@
[book]
authors = ["peaceiris"]
language = "en"
multilingual = false
src = "src"
title = "GitHub Actions for GitHub Pages"

View File

@ -1,3 +0,0 @@
# Summary
- [Chapter 1](./chapter_1.md)

View File

@ -1,3 +0,0 @@
# Chapter 1
test 7

View File

@ -1,16 +0,0 @@
{
"compilerOptions": {
"lib": ["ES2019"],
"module": "commonjs",
"target": "ES2019",
"sourceMap": true,
"outDir": "./lib",
"rootDir": "./src",
"removeComments": true,
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"exclude": ["node_modules", "**/*.test.ts"]
}