So I was using FTP-Deploy-Action and ran into an issue, but looking at the code, it seemed more relevant to file the issue in this repo - LMK if you want me to move it. Let me explain what I'm doing.
The website I'm deploying has:
- an
assets directory containing fingerprinted css and js files
- an
index.html file that loads fingerprinted assets and runs the app
- a
build.json file that is generated at build time with the commit sha, which the app polls for to see if it has changed, at which time it reloads the app
eg.
build/client/
|-- assets
| |-- api-CxujkEL4.js
| |-- build-info-uX_ocp1e.js
| |-- chunk-KNED5TY2-B2LzAy-9.js
| |-- (etc)
| |-- test-nav-Df4njhOQ.css
| |-- test-nav-QvsV6Ysp.js
| `-- with-props-ColFkw8L.js
|-- build.json
`-- index.html
The problem Im running into is that I have no way to specify the order in which these files are uploaded. However, the files must be uploaded in a very specific order:
- All new fingerprinted asset files must first be uploaded. If a user loads the app, or the upload fails during this step, the app will continue to work as before, because nothing has changed with any existing files.
- The
index.html file may now be uploaded. Once this file is uploaded, any user loading the app will see the new version.
- The
build.json file may now be uploaded. Once this file is uploaded, the app will see the change and reload itself.
- No-longer-used files may now be deleted from the server.
If step 2 happens before the asset files are uploaded, any user loading the app would run into problems, because necessary asset files don't exist on the server yet.
If step 3 happens before index.html is uploaded, the app would reload itself prematurely and see no changes, because index.html wouldn't be on the server yet, so it would reload the old version. Once index.html was uploaded, the app would have no way of knowing it needed to re-reload itself.
Right now, I'm working around this limitation like so, but as you can imagine, this isn't ideal, as it adds complexity and makes the entire deploy process take significantly longer.
name: Deploy Web Dev
on:
push:
branches: [main]
jobs:
deploy-dev:
runs-on: ubuntu-latest
concurrency:
group: deploy-dev
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- run: npm ci
- run: npm run build-ci
# step 1: Upload fingerprinted assets, use a dummy state file so it doesn't delete anything.
# Unfortunately, this will re-upload unchanged files.
- name: ftp deploy - step 1 - fingerprinted assets
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
local-dir: ./build/client/
username: ci
password: ${{ secrets.FTP_PASSWORD }}
server: ${{ secrets.FTP_SERVER }}
state-name: ftp-deploy-sync-state-dummy-1.json
exclude: |
index.html
build.json
# step 2: Upload index.html which effectively makes the new version go live, still don't delete anything.
- run: rm ./build/client/ftp-deploy-sync-state-dummy-1.json
- name: ftp deploy - step 2 - index.html
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
local-dir: ./build/client/
username: ci
password: ${{ secrets.FTP_PASSWORD }}
server: ${{ secrets.FTP_SERVER }}
state-name: ftp-deploy-sync-state-dummy-2.json
exclude: |
assets/**
build.json
# step 3: Upload build.json so that app can auto-update, overwrite dummy state files, delete as usual.
# Also, force-upload new dummy state files so no files will be deleted in steps 1+2 next time.
- run: echo "cachebust-${{ github.run_id }}" > ./build/client/ftp-deploy-sync-state-dummy-1.json
- run: echo "cachebust-${{ github.run_id }}" > ./build/client/ftp-deploy-sync-state-dummy-2.json
- name: ftp deploy - step 3 - build.json
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
local-dir: ./build/client/
username: ci
password: ${{ secrets.FTP_PASSWORD }}
server: ${{ secrets.FTP_SERVER }}
So, here's the ask. Can an option be added to this library and to FTP-Deploy-Action that lets the user specify the order in which files should be uploaded?
It could possibly just be an array of glob patterns (like how exclude works). The glob patterns would be iterated over in order, and for each one, all not-already-added matching files would be added to a sorted output array.
The underlying code would be something along these lines:
function sortFiles(files, patterns) {
const map = {};
const sortedFiles = [];
patterns.forEach((pattern) => {
const files = multimatch(unsortedFiles, pattern);
for (const file of files) {
if (!map[file]) {
map[file] = true;
sortedFiles.push(file);
}
}
});
return sortedFiles;
}
Eg.
const unsortedFiles = [
"build.json",
"index.html",
"assets/home-C6JigMfh.js",
"assets/chunk-KNED5TY2-B2LzAy-9.js",
"assets/build-info-uX_ocp1e.js",
"assets/overlay-B98S4KzY.css",
"assets/test-Dfnwt5EG.css",
"assets/entry.client-Jga_eV3f.js",
];
const sortPatterns = ["assets/**", "index.html", "build.json"];
const sortedFiles = sortFiles(unsortedFiles, sortPatterns);
console.log(sortedFiles);
/*
[
"assets/home-C6JigMfh.js",
"assets/chunk-KNED5TY2-B2LzAy-9.js",
"assets/build-info-uX_ocp1e.js",
"assets/overlay-B98S4KzY.css",
"assets/test-Dfnwt5EG.css",
"assets/entry.client-Jga_eV3f.js",
"index.html",
"build.json",
]
*/
Which would allow me (or anyone else deploying a static generated site with fingerprinted assets) to do this:
- name: ftp deploy
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
local-dir: ./build/client/
username: ci
password: ${{ secrets.FTP_PASSWORD }}
server: ${{ secrets.FTP_SERVER }}
order: |
assets/**
index.html
build.json
Thanks!
So I was using FTP-Deploy-Action and ran into an issue, but looking at the code, it seemed more relevant to file the issue in this repo - LMK if you want me to move it. Let me explain what I'm doing.
The website I'm deploying has:
assetsdirectory containing fingerprinted css and js filesindex.htmlfile that loads fingerprinted assets and runs the appbuild.jsonfile that is generated at build time with the commit sha, which the app polls for to see if it has changed, at which time it reloads the appeg.
The problem Im running into is that I have no way to specify the order in which these files are uploaded. However, the files must be uploaded in a very specific order:
index.htmlfile may now be uploaded. Once this file is uploaded, any user loading the app will see the new version.build.jsonfile may now be uploaded. Once this file is uploaded, the app will see the change and reload itself.If step 2 happens before the asset files are uploaded, any user loading the app would run into problems, because necessary asset files don't exist on the server yet.
If step 3 happens before
index.htmlis uploaded, the app would reload itself prematurely and see no changes, becauseindex.htmlwouldn't be on the server yet, so it would reload the old version. Onceindex.htmlwas uploaded, the app would have no way of knowing it needed to re-reload itself.Right now, I'm working around this limitation like so, but as you can imagine, this isn't ideal, as it adds complexity and makes the entire deploy process take significantly longer.
So, here's the ask. Can an option be added to this library and to FTP-Deploy-Action that lets the user specify the order in which files should be uploaded?
It could possibly just be an array of glob patterns (like how
excludeworks). The glob patterns would be iterated over in order, and for each one, all not-already-added matching files would be added to a sorted output array.The underlying code would be something along these lines:
Eg.
Which would allow me (or anyone else deploying a static generated site with fingerprinted assets) to do this:
Thanks!