Compare commits

..

No commits in common. "master" and "v4.1.0" have entirely different histories.

12 changed files with 4486 additions and 6485 deletions

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: ./ uses: ./

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: ./ uses: ./

View File

@ -20,10 +20,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.5 uses: SamKirkland/FTP-Deploy-Action@4.1.0
with: with:
server: ftp.samkirkland.com server: ftp.samkirkland.com
username: myFtpUserName username: myFtpUserName
@ -33,7 +33,7 @@ jobs:
--- ---
### Requirements ### Requirements
- You must have ftp access to your server. If your host allows or requires ssh please use my [web-deploy](https://github.com/SamKirkland/web-deploy) action - You must have ftp access to your server. If your host requires ssh please use my web-deploy action (coming soon)
- Some web hosts change the default port (21), check with your host for your port number - Some web hosts change the default port (21), check with your host for your port number
--- ---
@ -55,22 +55,21 @@ Keys can be added directly to your .yml config file or referenced from your proj
To add a `secret` go to the `Settings` tab in your project then select `Secrets`. To add a `secret` go to the `Settings` tab in your project then select `Secrets`.
I strongly recommend you store your `password` as a secret. I strongly recommend you store your `password` as a secret.
| Key Name | Required | Example | Default Value | Description | | Key Name | Required | Example | Default Value | Description |
|-------------------------|----------|-------------------------------|-------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------------|----------|----------------------------|-----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `server` | Yes | `ftp.samkirkland.com` | | Deployment destination server | | `server` | Yes | `ftp.samkirkland.com` | | Deployment destination server |
| `username` | Yes | `username@samkirkland.com` | | FTP user name | | `username` | Yes | `username@samkirkland.com` | | FTP user name |
| `password` | Yes | `CrazyUniquePassword&%123` | | FTP password, be sure to escape quotes and spaces | | `password` | Yes | `CrazyUniquePassword&%123` | | FTP password, be sure to escape quotes and spaces |
| `port` | No | `990` | `21` | Server port to connect to (read your web hosts docs) | | `port` | No | `990` | `21` | Server port to connect to (read your web hosts docs) |
| `protocol` | No | `ftps` | `ftp` | `ftp`: provides no encryption, `ftps`: full encryption newest standard (aka "explicit" ftps), `ftps-legacy`: full encryption legacy standard (aka "implicit" ftps) | | `protocol` | No | `ftps` | `ftp` | `ftp`: provides no encryption, `ftps`: full encryption newest standard (aka "explicit" ftps), `ftps-legacy`: full encryption legacy standard (aka "implicit" ftps) |
| `local-dir` | No | `./myFolderToPublish/` | `./` | Folder to upload from, must end with trailing slash `/` | | `local-dir` | No | `./myFolderToPublish/` | `./` | Folder to upload from, must end with trailing slash `/` |
| `server-dir` | No | `public_html/www/` | `./` | Folder to upload to (on the server), must end with trailing slash `/` | | `server-dir` | No | `public_html/www/` | `./` | Folder to upload to (on the server), must end with trailing slash `/` |
| `state-name` | No | `folder/.sync-state.json` | `.ftp-deploy-sync-state.json` | Path and name of the state file - this file is used to track which files have been deployed | | `state-name` | No | `folder/.sync-state.json` | `.ftp-deploy-sync-state.json` | Path and name of the state file - this file is used to track which files have been deployed |
| `dry-run` | No | `true` | `false` | Prints which modifications will be made with current config options, but doesn't actually make any changes | | `dry-run` | No | `true` | `false` | Prints which modifications will be made with current config options, but doesn't actually make any changes |
| `dangerous-clean-slate` | No | `true` | `false` | Deletes ALL contents of server-dir, even items in excluded with 'exclude' argument | | `dangerous-clean-slate` | No | `true` | `false` | Deletes ALL contents of server-dir, even items in excluded with 'exclude' argument |
| `exclude` | No | [See Example](#exclude-files) | [See Example](#exclude-files) | An array of glob patterns, these files will not be included in the publish/delete process. [List MUST be in this format](#exclude-files). You can use [a glob tester](https://www.digitalocean.com/community/tools/glob?comments=true&glob=%2A%2A%2F.git%2A%2F%2A%2A&matches=false&tests=test%2Fsam&tests=.git%2F%0D&tests=.github%2F%0D&tests=.git%2Ftest%0D&tests=.gitattributes%0D&tests=.gitignore%0D&tests=.git%2Fconfig%0D&tests=.git%2Ftest%2Ftest&tests=.github%2Fworkflows%2Fmain.yml&tests=node_modules%2Ffolder%2F%0D&tests=node_modules%2Fotherfolder%2F%0D&tests=subfolder%2Fnode_modules%2F) to test your pattern(s). | | `exclude` | No | | `**/.git*` `**/.git*/**` `**/node_modules/**` | An array of glob patterns, these files will not be included in the publish/delete process. [List must be in yaml array format](#exclude-files). You can use [a glob tester](https://www.digitalocean.com/community/tools/glob?comments=true&glob=%2A%2A%2F.git%2A%2F%2A%2A&matches=false&tests=test%2Fsam&tests=.git%2F&tests=.github%2F&tests=.git%2Ftest&tests=.gitattributes&tests=.gitignore&tests=.git%2Fconfig&tests=.git%2Ftest%2Ftest&tests=.github%2Fworkflows%2Fmain.yml&tests=test%2F.git%2Fworkflows%2Fmain.yml&tests=node_modules%2Ffolder%2F&tests=node_modules%2Fotherfolder%2F&tests=subfolder%2Fnode_modules%2F) to test your pattern(s). |
| `log-level` | No | `minimal` | `standard` | `minimal`: only important info, `standard`: important info and basic file changes, `verbose`: print everything the script is doing | | `log-level` | No | `minimal` | `standard` | `minimal`: only important info, `standard`: important info and basic file changes, `verbose`: print everything the script is doing |
| `security` | No | `strict` | `loose` | `strict`: Reject any connection which is not authorized with the list of supplied CAs. `loose`: Allow connection even when the domain is not certificate | | `security` | No | `strict` | `loose` | `strict`: Reject any connection which is not authorized with the list of supplied CAs. `loose`: Allow connection even when the domain is not certificate |
| `timeout` | No | `60000` | `30000` | Timeout in milliseconds for FTP operations |
# Common Examples # Common Examples
@ -86,12 +85,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Use Node.js 16 - name: Use Node.js 12
uses: actions/setup-node@v2 uses: actions/setup-node@v2-beta
with: with:
node-version: '16' node-version: '12'
- name: 🔨 Build Project - name: 🔨 Build Project
run: | run: |
@ -99,7 +98,7 @@ jobs:
npm run build npm run build
- name: 📂 Sync files - name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.5 uses: SamKirkland/FTP-Deploy-Action@4.1.0
with: with:
server: ftp.samkirkland.com server: ftp.samkirkland.com
username: myFtpUserName username: myFtpUserName
@ -116,10 +115,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.5 uses: SamKirkland/FTP-Deploy-Action@4.1.0
with: with:
server: ftp.samkirkland.com server: ftp.samkirkland.com
username: myFtpUserName username: myFtpUserName
@ -128,7 +127,7 @@ jobs:
port: 1234 # todo replace with your web hosts ftps port port: 1234 # todo replace with your web hosts ftps port
``` ```
#### Log only dry run: Use this option for testing #### Log only dry run: Use this mode for testing
Ouputs a list of files that will be created/modified to sync your source without making any actual changes Ouputs a list of files that will be created/modified to sync your source without making any actual changes
```yml ```yml
on: push on: push
@ -139,10 +138,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.5 uses: SamKirkland/FTP-Deploy-Action@4.1.0
with: with:
server: ftp.samkirkland.com server: ftp.samkirkland.com
username: myFtpUserName username: myFtpUserName
@ -161,33 +160,21 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 🚚 Get latest code - name: 🚚 Get latest code
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: 📂 Sync files - name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.5 uses: SamKirkland/FTP-Deploy-Action@4.1.0
with: with:
server: ftp.samkirkland.com server: ftp.samkirkland.com
username: myFtpUserName username: myFtpUserName
password: ${{ secrets.password }} password: ${{ secrets.password }}
exclude: | exclude:
**/.git* - **/.git*
**/.git*/** - **/.git*/**
**/node_modules/** - **/node_modules/**
fileToExclude.txt - fileToExclude.txt
``` ```
`exclude` has the following default value
```yml
exclude: |
**/.git*
**/.git*/**
**/node_modules/**
```
if you overwrite the default value you will probably want to respecify them
---
_Want another example? Let me know by creating a [github issue](https://github.com/SamKirkland/FTP-Deploy-Action/issues/new)_ _Want another example? Let me know by creating a [github issue](https://github.com/SamKirkland/FTP-Deploy-Action/issues/new)_
--- ---

View File

@ -41,12 +41,9 @@ inputs:
security: security:
required: false required: false
description: "strict or loose" description: "strict or loose"
timeout:
required: false
description: "Timeout in milliseconds for FTP operations"
runs: runs:
using: "node20" using: "node12"
main: "dist/index.js" main: "dist/index.js"
branding: branding:
icon: "upload-cloud" icon: "upload-cloud"
color: "blue" color: "orange"

3251
dist/index.js vendored

File diff suppressed because it is too large Load Diff

3
jest.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
preset: "ts-jest"
};

View File

@ -1,40 +1,23 @@
# How to migrate between versions # Migrating from v3 to v4
## Migrating from v4.1.0 to v4.2.0
`v4.2.0` parses the `exclude` option in a more standard way. Going forward the `exclude` option **must** be in the following format:
```yml
exclude: |
**/.git*
**/.git*/**
**/node_modules/**
fileToExclude.txt
```
## Migrating from v3 to v4
Migrating from v3 to v4 should be fairly straightforward. Version 4 was designed with speed and ease of initial setup in mind. Going forward version 4 will be the only supported version. Migrating from v3 to v4 should be fairly straightforward. Version 4 was designed with speed and ease of initial setup in mind. Going forward version 4 will be the only supported version.
### Those who can't upgrade #### Those who can't upgrade
Most features have been carried forward and improved upon. However, some features did not make the cut.
Most features have been carried forward and improved upon. However, some features did not make the cut:
- **`sftp` is no longer supported**. If you have `sftp` access you are using `ssh`, that means you have access to a much more modern and capable protocol. I plan on releasing a separate github action that will deploy over `sftp`/`ssh` using `rsync`. Until then you can continue using version 3. - **`sftp` is no longer supported**. If you have `sftp` access you are using `ssh`, that means you have access to a much more modern and capable protocol. I plan on releasing a separate github action that will deploy over `sftp`/`ssh` using `rsync`. Until then you can continue using version 3.
- The `include` argument has been removed. I didn't see much need for it in the initial release. If you need this feature please create a support ticket. - The `include` argument has been removed. I didn't see much need for it in the initial release. If you need this feature please create a support ticket.
---
### How to upgrade ### How to upgrade
1. Remove `with: fetch-depth: 2`. It is no longer needed and removing it will _slightly_ speed up deployments. 1) Remove `with: fetch-depth: 2`. It is no longer needed and removing it will _slightly_ speed up deployments.
2. Change the version to `v4.X.X`, for example `SamKirkland/FTP-Deploy-Action@v4.3.5` (please check the [README](https://github.com/SamKirkland/FTP-Deploy-Action/blob/master/README.md) or the [releases page](https://github.com/SamKirkland/FTP-Deploy-Action/releases/latest) for the latest version). 2) Change the version to `4.X.X`, for example `SamKirkland/FTP-Deploy-Action@4.1.0` (please check readme for latest version)
3. If you have a `.git-ftp-include` file you should delete it. Version 4 tracks files differently and no longer needs this config file. 3) If you have a `.git-ftp-include` file you should delete it. Version 4 tracks files differently and no longer needs this config file.
4. If you have a `.git-ftp-ignore` file, you should transfer the options to the new `exclude` argument. **Note:** version 4 excludes any `.git*` and `node_modules/` files / folders by default. 4) If you have a `.git-ftp-ignore` file, you should transfer the options to the new `exclude` argument. _Note: Version 4 excludes any `.git*` and `node_modules/` files/folders by default_
5. Update your arguments to reflect the following changes: 5) Update your arguments to reflect the following changes
- `ftp-server` was split into 4 arguments: * `ftp-server` was split into 4 arguments. `server`, `port`, `protocol`, and `server-dir`. Transfer your config to these options as needed.
- `server` * `ftp-username` was renamed to `username`
- `port` * `ftp-password` was renamed to `password`
- `protocol` * `local-dir` and `server-dir` now **must** end with `/`
- `server-dir` * `git-ftp-args` and `known-hosts` arguments were removed
- `ftp-username` was renamed to `username`.
- `ftp-password` was renamed to `password`.
- `local-dir` and `server-dir` now **must** end with `/`.
- `git-ftp-args` and `known-hosts` arguments were removed.

7488
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "ftp-deploy-action", "name": "ftp-deploy-action",
"version": "4.3.5", "version": "4.1.0",
"private": true, "private": true,
"description": "Automate deploying websites and more with this GitHub action", "description": "Automate deploying websites and more with this GitHub action",
"main": "dist/index.js", "main": "dist/index.js",
@ -22,23 +22,20 @@
"author": "Sam Kirkland", "author": "Sam Kirkland",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.9.1", "@actions/core": "^1.4.0",
"@samkirkland/ftp-deploy": "^1.2.4", "@samkirkland/ftp-deploy": "^1.1.0",
"@types/jest": "^29.4.1", "@types/jest": "^26.0.23",
"jest": "^29.5.0", "jest": "^27.0.5",
"ts-jest": "^29.0.5", "ts-jest": "^27.0.3",
"ts-node-dev": "^2.0.0" "ts-node-dev": "^1.1.6"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.11.24", "@types/node": "^14.0.27",
"@typescript-eslint/eslint-plugin": "^5.33.1", "@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^5.33.1", "@typescript-eslint/parser": "^4.28.0",
"@vercel/ncc": "^0.34.0", "@vercel/ncc": "^0.28.6",
"eslint": "^8.22.0", "eslint": "^7.29.0",
"eslint-plugin-jest": "^26.8.7", "eslint-plugin-jest": "^24.3.6",
"typescript": "^4.7.4" "typescript": "^4.3.4"
},
"jest": {
"preset": "ts-jest"
} }
} }

View File

@ -1,4 +1,4 @@
import { optionalBoolean, optionalInt, optionalLogLevel, optionalProtocol, optionalSecurity, optionalString } from "./parse"; import { optionalBoolean, optionalInt, optionalLogLevel, optionalProtocol, optionalSecurity, optionalString, optionalStringArray } from "./parse";
describe("boolean", () => { describe("boolean", () => {
test("false", () => { test("false", () => {
@ -103,3 +103,33 @@ describe("security", () => {
expect(optionalSecurity("test", "strict")).toBe("strict"); expect(optionalSecurity("test", "strict")).toBe("strict");
}); });
}); });
describe("array", () => {
test("empty", () => {
expect(optionalStringArray("test", "")).toEqual(undefined);
});
test("empty array", () => {
expect(optionalStringArray("test", "[]")).toEqual([]);
});
test(`["test.txt"]`, () => {
expect(optionalStringArray("test", "[test.txt]")).toEqual(["test.txt"]);
});
test(`[ "test.txt" ]`, () => {
expect(optionalStringArray("test", "[ test.txt ]")).toEqual(["test.txt"]);
});
test(`["test.txt", "folder/**/*"]`, () => {
expect(optionalStringArray("test", "[test.txt, folder/**/*]")).toEqual(["test.txt", "folder/**/*"]);
});
test(`["test.txt", "folder/**/*", "*other"]`, () => {
expect(optionalStringArray("test", `test.txt\n - folder/**/*\n - *other`)).toEqual(["test.txt", "folder/**/*", "*other"]);
});
test(`["test.txt", "folder/**/*", "*other"]`, () => {
expect(optionalStringArray("test", `\n - test.txt\n - folder/**/*\n - *other`)).toEqual(["test.txt", "folder/**/*", "*other"]);
});
});

View File

@ -16,15 +16,14 @@ async function runDeployment() {
"state-name": optionalString(core.getInput("state-name")), "state-name": optionalString(core.getInput("state-name")),
"dry-run": optionalBoolean("dry-run", core.getInput("dry-run")), "dry-run": optionalBoolean("dry-run", core.getInput("dry-run")),
"dangerous-clean-slate": optionalBoolean("dangerous-clean-slate", core.getInput("dangerous-clean-slate")), "dangerous-clean-slate": optionalBoolean("dangerous-clean-slate", core.getInput("dangerous-clean-slate")),
"exclude": optionalStringArray("exclude", core.getMultilineInput("exclude")), "exclude": optionalStringArray("exclude", core.getInput("exclude")),
"log-level": optionalLogLevel("log-level", core.getInput("log-level")), "log-level": optionalLogLevel("log-level", core.getInput("log-level")),
"security": optionalSecurity("security", core.getInput("security")), "security": optionalSecurity("security", core.getInput("security"))
"timeout": optionalInt("timeout", core.getInput("timeout"))
}; };
await deploy(args); await deploy(args);
} }
catch (error: any) { catch (error) {
core.setFailed(error); core.setFailed(error);
} }
} }

View File

@ -90,14 +90,24 @@ export function optionalInt(argumentName: string, rawValue: string): number | un
throw new Error(`${argumentName}: invalid parameter - you provided "${rawValue}". Try a whole number (no decimals) instead like 1234`); throw new Error(`${argumentName}: invalid parameter - you provided "${rawValue}". Try a whole number (no decimals) instead like 1234`);
} }
export function optionalStringArray(argumentName: string, rawValue: string[]): string[] | undefined { export function optionalStringArray(argumentName: string, rawValue: string): string[] | undefined {
if (rawValue.length === 0) { if (rawValue.length === 0) {
return undefined; return undefined;
} }
if (typeof rawValue === "string") { const valueTrim = rawValue.trim();
throw new Error(`${argumentName}: invalid parameter - you provided "${rawValue}". This option expects an list in the EXACT format described in the readme`);
if (valueTrim.startsWith("[")) {
// remove [ and ] - then convert to array
return rawValue.replace(/[\[\]]/g, "").trim().split(", ").filter(str => str !== "");
} }
return rawValue; // split value by space and comma
const valueAsArrayDouble = rawValue.split(" - ").map(str => str.trim()).filter(str => str !== "");
if (valueAsArrayDouble.length) {
return valueAsArrayDouble;
}
throw new Error(`${argumentName}: invalid parameter - you provided "${rawValue}". This option excepts an array in the format [val1, val2] or val1\/n - val2`);
} }