mirror of
https://github.com/bcomnes/deploy-to-neocities.git
synced 2026-01-16 22:56:28 +00:00
Update to the latest async-neocities 4.0
BREAKING CHANGE: api_token action input is renamed to api_key, please update this BREAKING CHANGE: added a required neocities_supporter action input to toggle unsupported file filtering BREAKING CHANGE: addad a preview_before_deploy action input to toggle informational deploy plans prior to deploys BREAKING CHANGE: completely rewrote the underlying library to provide better error handling and reporting BREAKING CHANGE: Remove a bunch of real time stats and progress meters. Deploys were finishing in seconds and these were very complicated to maintain.
This commit is contained in:
parent
f9a550fd47
commit
7b14798c89
4
.github/workflows/neocities.yml
vendored
4
.github/workflows/neocities.yml
vendored
@ -32,7 +32,9 @@ jobs:
|
||||
- name: Deploy to neocities
|
||||
uses: bcomnes/deploy-to-neocities@master # dont use master in production
|
||||
with:
|
||||
api_token: ${{ secrets.NEOCITIES_API_TOKEN }}
|
||||
api_key: ${{ secrets.NEOCITIES_API_TOKEN }}
|
||||
cleanup: true
|
||||
dist_dir: public
|
||||
protected_files: 'dropbox/*'
|
||||
neocities_supporter: true # set this to true if you have a supporter account and want to bypass unsuported files filter.
|
||||
preview_before_deploy: true
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ public
|
||||
node_modules
|
||||
tmp_modules
|
||||
package-lock.json
|
||||
coverage
|
||||
|
||||
15
README.md
15
README.md
@ -10,6 +10,8 @@
|
||||
|
||||
Efficiently deploy a website to [Neocities][nc] using [Github actions](https://github.com/features/actions). Uses content aware diffing to only update files that changed.
|
||||
|
||||
Alternatively, you can use the bin helper in [async-neocities](https://github.com/bcomnes/async-neocities) to deploy to neocities locally from your own machine as well as in CI.
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
@ -30,23 +32,26 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
# Set up any tools and build steps here
|
||||
# This example uses a Node.js toolchain to build a site
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
# If you have a different build process, replace this with your own build steps
|
||||
- name: Install deps and build
|
||||
run: |
|
||||
npm i
|
||||
npm run build
|
||||
# When the dist_dir is ready, deploy it to neocities
|
||||
- name: Deploy to neocities
|
||||
uses: bcomnes/deploy-to-neocities@v2
|
||||
uses: bcomnes/deploy-to-neocities@v3
|
||||
with:
|
||||
api_token: ${{ secrets.NEOCITIES_API_TOKEN }}
|
||||
api_key: ${{ secrets.NEOCITIES_API_TOKEN }}
|
||||
cleanup: false
|
||||
neocities_supporter: false # set this to true if you have a supporter account and want to bypass unsuported files filter.
|
||||
preview_before_deploy: true # print a deployment plan prior to waiting for files to upload.
|
||||
dist_dir: public
|
||||
```
|
||||
|
||||
@ -73,7 +78,9 @@ You most likely only want to run this on the `master` branch so that only change
|
||||
|
||||
- `api_token` (**REQUIRED**): The API token for your [Neocities][nc] website to deploy to.
|
||||
- `dist_dir`: The directory to deploy to [Neocities][nc]. Default: `public`. Don't deploy your root repo directory (e.g. `./`). It contains `.git`, `.github` and other files that won't deploy properly to neocities. Keep it clean by keeping or building your site into a subdir and deploy that.
|
||||
- `neocoties_supporter`: Set this to `true` if you have a paid neocities account and want to bypass the [unsupported files filter](https://neocities.org/site_files/allowed_types).
|
||||
- `cleanup`: Boolean string (`true` or `false`). If `true`, `deploy-to-neocities` will destructively delete files found on [Neocities][nc] not found in your `dist_dir`. Default: `false`.
|
||||
- `preview_before_deploy`: Boolean string (`true` or `false`). If `true`, `deploy-to-neocities` will print a preview of the files that will be uploaded and deleted. Default: `true`.
|
||||
- `protected_files`: An optional glob string used to mark files as protected. Protected files are never cleaned up. Test this option out with `cleanup` set to false before relying on it. Protected files are printed when `cleanup` is set to true or false. Glob strings are processed by [minimatch](https://github.com/isaacs/minimatch) against remote neocities file paths. Protected files can still be updated.
|
||||
|
||||
### Outputs
|
||||
|
||||
20
action.yml
20
action.yml
@ -4,20 +4,32 @@ branding:
|
||||
icon: aperture
|
||||
color: orange
|
||||
inputs:
|
||||
api_token: # api token for site to deploy to
|
||||
description: 'Neocities API token for site to deploy to'
|
||||
api_key: # api token for site to deploy to
|
||||
description: 'Neocities API key for site to deploy to'
|
||||
required: true
|
||||
dist_dir:
|
||||
description: 'Local folder to deploy to neocities'
|
||||
default: 'public'
|
||||
required: true
|
||||
neocities_supporter:
|
||||
description: 'Set to true if you are a Neocities supporter to bypass file type upload restrictions'
|
||||
default: 'false'
|
||||
required: true
|
||||
cleanup:
|
||||
description: Delete orphaned files on neocities that don't exist in distDir
|
||||
default: false
|
||||
default: 'false'
|
||||
required: true
|
||||
preview_before_deploy:
|
||||
description: 'Set to true if you want to print deploy preview stats prior to deploying.'
|
||||
default: 'true'
|
||||
required: false
|
||||
protected_files:
|
||||
description: A glob string that prevents matched files from ever being deleted.
|
||||
required: false
|
||||
api_token: # api token for site to deploy to
|
||||
description: 'Neocities API key for site to deploy to'
|
||||
required: false
|
||||
deprecationMessage: 'api_token is deprecated, use api_key instead'
|
||||
runs:
|
||||
using: 'node20'
|
||||
main: 'dist/index.js'
|
||||
main: 'dist/index.cjs'
|
||||
|
||||
31890
dist/index.js → dist/index.cjs
vendored
31890
dist/index.js → dist/index.cjs
vendored
File diff suppressed because one or more lines are too long
7
dist/index.cjs.map
vendored
Normal file
7
dist/index.cjs.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
dist/index.js.map
vendored
7
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
8237
dist/meta.json
vendored
Normal file
8237
dist/meta.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
eslint.config.js
Normal file
8
eslint.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
import neostandard, { resolveIgnoresFromGitignore } from 'neostandard'
|
||||
|
||||
export default neostandard({
|
||||
ignores: [
|
||||
...resolveIgnoresFromGitignore(),
|
||||
'dist'
|
||||
],
|
||||
})
|
||||
113
index.js
113
index.js
@ -1,57 +1,84 @@
|
||||
const core = require('@actions/core')
|
||||
// const github = require('@actions/github')
|
||||
const Neocities = require('async-neocities')
|
||||
const path = require('path')
|
||||
const ms = require('ms')
|
||||
const assert = require('webassert').default
|
||||
const fsp = require('fs').promises
|
||||
const { minimatch } = require('minimatch')
|
||||
const { stackWithCauses } = require('pony-cause')
|
||||
import core from '@actions/core'
|
||||
import {
|
||||
NeocitiesAPIClient,
|
||||
printDeployText,
|
||||
printPreviewText,
|
||||
printResultsErrorDump,
|
||||
SimpleTimer
|
||||
} from 'async-neocities'
|
||||
import path from 'node:path'
|
||||
import assert from 'node:assert'
|
||||
import fs from 'node:fs/promises'
|
||||
import { minimatch } from 'minimatch'
|
||||
|
||||
let cleanup
|
||||
|
||||
async function doDeploy () {
|
||||
const token = core.getInput('api_token')
|
||||
async function run () {
|
||||
const key = core.getInput('api_key') || core.getInput('api_token')
|
||||
const distDir = path.join(process.cwd(), core.getInput('dist_dir'))
|
||||
cleanup = JSON.parse(core.getInput('cleanup'))
|
||||
const cleanup = JSON.parse(core.getInput('cleanup'))
|
||||
const neocitiesSupporter = JSON.parse(core.getInput('neocities_supporter'))
|
||||
const previewDeploy = JSON.parse(core.getInput('preview_before_deploy'))
|
||||
const protectedFilesGlob = core.getInput('protected_files')
|
||||
|
||||
assert(typeof cleanup === 'boolean', 'Cleanup input must be a boolean "true" or "false"')
|
||||
const stat = await fsp.stat(distDir)
|
||||
assert(stat.isDirectory(), 'dist_dir must be a directory that exists')
|
||||
assert(typeof cleanup === 'boolean', '`cleanup` input must be a boolean "true" or "false"')
|
||||
assert(typeof neocitiesSupporter === 'boolean', '`neocities_supporter` input must be a boolean "true" or "false"')
|
||||
assert(typeof previewDeploy === 'boolean', '`preview_before_deploy` input must be a boolean "true" or "false"')
|
||||
|
||||
const client = new Neocities(token)
|
||||
const stat = await fs.stat(distDir)
|
||||
|
||||
const deployOpts = {
|
||||
cleanup,
|
||||
statsCb: Neocities.statsHandler()
|
||||
assert(stat.isDirectory(), '`dist_dir` input must be a path to a directory that exists')
|
||||
|
||||
const client = new NeocitiesAPIClient(key)
|
||||
|
||||
if (previewDeploy) {
|
||||
const previewTimer = new SimpleTimer()
|
||||
console.log('Running deploy preview prior to deployment...\n\n')
|
||||
|
||||
const diff = await client.previewDeploy({
|
||||
directory: distDir,
|
||||
includeUnsupportedFiles: neocitiesSupporter,
|
||||
protectedFileFilter: protectedFilesGlob ? minimatch.filter(protectedFilesGlob) : undefined
|
||||
})
|
||||
|
||||
previewTimer.stop()
|
||||
|
||||
printPreviewText({
|
||||
diff,
|
||||
timer: previewTimer,
|
||||
cleanup,
|
||||
includeUnsupportedFiles: neocitiesSupporter
|
||||
})
|
||||
}
|
||||
|
||||
if (protectedFilesGlob) deployOpts.protectedFileFilter = minimatch.filter(protectedFilesGlob)
|
||||
const deployTimer = new SimpleTimer()
|
||||
console.log('Deploying to Neocities...')
|
||||
|
||||
const stats = await client.deploy(distDir, deployOpts)
|
||||
const results = await client.deploy({
|
||||
directory: distDir,
|
||||
cleanup,
|
||||
includeUnsupportedFiles: neocitiesSupporter,
|
||||
protectedFileFilter: protectedFilesGlob ? minimatch.filter(protectedFilesGlob) : undefined
|
||||
})
|
||||
|
||||
console.log(`Deployed to Neocities in ${ms(stats.time)}:`)
|
||||
console.log(` Uploaded ${stats.filesToUpload.length} files`)
|
||||
console.log(` ${cleanup ? 'Deleted' : 'Orphaned'} ${stats.filesToDelete.length} files`)
|
||||
console.log(` Skipped ${stats.filesSkipped.length} files`)
|
||||
console.log(` ${stats.protectedFiles.length} protected files:`)
|
||||
if (stats.protectedFiles.length) {
|
||||
console.log(stats.protectedFiles)
|
||||
deployTimer.stop()
|
||||
|
||||
if (results.errors.length > 0) {
|
||||
printResultsErrorDump({
|
||||
results,
|
||||
timer: deployTimer
|
||||
})
|
||||
core.setFailed('The deploy completed with errors.')
|
||||
} else {
|
||||
printDeployText({
|
||||
results,
|
||||
timer: deployTimer,
|
||||
cleanup,
|
||||
includeUnsupportedFiles: neocitiesSupporter
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
doDeploy().catch(err => {
|
||||
console.error(stackWithCauses(err))
|
||||
if (err.stats) {
|
||||
console.log('Files to upload: ')
|
||||
console.dir(err.stats.filesToUpload, { colors: true, depth: 999 })
|
||||
|
||||
if (cleanup) {
|
||||
console.log('Files to delete: ')
|
||||
console.dir(err.stats.filesToDelete, { colors: true, depth: 999 })
|
||||
}
|
||||
}
|
||||
|
||||
core.setFailed(err.message)
|
||||
run().catch(err => {
|
||||
console.log('Unexpected error/throw during deployment:\n\n')
|
||||
console.dir(err, { colors: true, depth: 999 })
|
||||
core.setFailed(err instanceof Error ? err.message : `An unexpected error occurred during deployment: ${err}`)
|
||||
})
|
||||
|
||||
33
package.json
33
package.json
@ -8,25 +8,25 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "1.11.1",
|
||||
"async-neocities": "2.1.6",
|
||||
"minimatch": "10.0.1",
|
||||
"ms": "2.1.3",
|
||||
"pony-cause": "^2.1.4",
|
||||
"webassert": "3.0.2"
|
||||
"async-neocities": "4.0.3",
|
||||
"minimatch": "10.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@voxpelli/tsconfig": "^15.0.0",
|
||||
"top-bun": "^10.0.0",
|
||||
"auto-changelog": "^2.0.0",
|
||||
"dependency-check": "^4.1.0",
|
||||
"gh-release": "^7.0.0",
|
||||
"npm-run-all2": "^7.0.1",
|
||||
"standard": "^17.0.0",
|
||||
"esbuild": "^0.24.0"
|
||||
"npm-run-all2": "^7.0.0",
|
||||
"neostandard": "^0.11.8",
|
||||
"c8": "^10.0.0",
|
||||
"esbuild": "~0.24.0",
|
||||
"typescript": "~5.6.2"
|
||||
},
|
||||
"homepage": "https://github.com/bcomnes/deploy-to-neocities#readme",
|
||||
"keywords": [],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -34,23 +34,20 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run clean && run-p build:*",
|
||||
"build:action": "rm -rf dist && esbuild index.js --bundle --platform=node --target=node16 --sourcemap=external --outdir=dist",
|
||||
"build:site": "tb --src . --dest public",
|
||||
"build:action": "rm -rf dist && esbuild index.js --bundle --platform=node --sourcemap=external --outdir=dist --metafile=dist/meta.json --out-extension:.js=.cjs",
|
||||
"build:site": "tb --src . --dest public --ignore dist,coverage",
|
||||
"dist-pkg": "echo \"{ \\\"type\\\": \\\"commonjs\\\" }\" > dist/package.json",
|
||||
"clean": "rm -rf public && mkdir -p public",
|
||||
"release": "git push --follow-tags && gh-release -y",
|
||||
"start": "npm run watch",
|
||||
"test": "run-s test:*",
|
||||
"test:deps": "dependency-check . --no-dev --no-peer",
|
||||
"test:standard": "standard",
|
||||
"test:lint": "eslint",
|
||||
"test:tsc": "tsc",
|
||||
"test:node": "c8 node --test",
|
||||
"version": "run-s version:*",
|
||||
"version:build": "npm run build:action && git add dist",
|
||||
"version:changelog": "auto-changelog -p --template keepachangelog auto-changelog --breaking-pattern 'BREAKING CHANGE:' && git add CHANGELOG.md",
|
||||
"watch": "npm run clean && run-p watch:*",
|
||||
"watch:site": "npm run build:site -- -w"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
7
test.js
7
test.js
@ -1,5 +1,6 @@
|
||||
const tap = require('tap')
|
||||
import assert from 'node:assert'
|
||||
import test from 'node:test'
|
||||
|
||||
tap.test('test', async t => {
|
||||
t.ok(true)
|
||||
test('test', async _t => {
|
||||
assert.ok(true)
|
||||
})
|
||||
|
||||
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "@voxpelli/tsconfig/node20.json",
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"public",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user