Skip to content

Commit 5be0b31

Browse files
authored
fix(ci): retry transient FTP deploy failures (#21)
* fix(ci): retry transient FTP deploy failures * fix(ci): encode FTP secrets in retry inputs * fix(ci): mask serialized FTP credentials * fix(ci): mask encoded FTP credentials before retries
1 parent bbaa5bf commit 5be0b31

1 file changed

Lines changed: 61 additions & 29 deletions

File tree

‎.github/workflows/deploy.yml‎

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,45 +37,77 @@ jobs:
3737
ls -la out/
3838
echo "Build output files:"
3939
find out/ -type f | head -10
40+
41+
- name: Mask serialized FTP credentials
42+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
43+
env:
44+
FTP_HOST_RAW: ${{ secrets.FTP_HOST }}
45+
FTP_USERNAME_RAW: ${{ secrets.FTP_USERNAME }}
46+
FTP_PASSWORD_RAW: ${{ secrets.FTP_PASSWORD }}
47+
run: |
48+
node <<'NODE'
49+
const names = ['FTP_HOST_RAW', 'FTP_USERNAME_RAW', 'FTP_PASSWORD_RAW'];
50+
const escapeCommandData = (value) => value
51+
.replace(/%/g, '%25')
52+
.replace(/\r/g, '%0D')
53+
.replace(/\n/g, '%0A');
54+
55+
for (const name of names) {
56+
const serialized = JSON.stringify(process.env[name] ?? '');
57+
process.stdout.write(`::add-mask::${escapeCommandData(serialized)}\n`);
58+
}
59+
NODE
4060
4161
- name: Deploy Next.js assets (excluding app chunks)
4262
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
43-
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
63+
uses: Wandalen/wretry.action@v3.8.0
4464
with:
45-
server: ${{ secrets.FTP_HOST }}
46-
username: ${{ secrets.FTP_USERNAME }}
47-
password: ${{ secrets.FTP_PASSWORD }}
48-
local-dir: ./out/_next/
49-
server-dir: ./_next/
50-
state-name: .ftp-deploy-sync-state.json
51-
exclude: |
52-
**/static/chunks/app/**
65+
action: SamKirkland/FTP-Deploy-Action@v4.3.6
66+
attempt_limit: 3
67+
attempt_delay: 15000
68+
with: |
69+
server: ${{ toJSON(secrets.FTP_HOST) }}
70+
username: ${{ toJSON(secrets.FTP_USERNAME) }}
71+
password: ${{ toJSON(secrets.FTP_PASSWORD) }}
72+
local-dir: ./out/_next/
73+
server-dir: ./_next/
74+
state-name: .ftp-deploy-sync-state.json
75+
exclude: |
76+
**/static/chunks/app/**
5377
5478
- name: Deploy Next.js app chunks
5579
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
56-
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
80+
uses: Wandalen/wretry.action@v3.8.0
5781
with:
58-
server: ${{ secrets.FTP_HOST }}
59-
username: ${{ secrets.FTP_USERNAME }}
60-
password: ${{ secrets.FTP_PASSWORD }}
61-
local-dir: ./out/_next/static/chunks/app/
62-
server-dir: ./_next/static/chunks/app/
63-
state-name: .ftp-deploy-sync-state.json
82+
action: SamKirkland/FTP-Deploy-Action@v4.3.6
83+
attempt_limit: 3
84+
attempt_delay: 15000
85+
with: |
86+
server: ${{ toJSON(secrets.FTP_HOST) }}
87+
username: ${{ toJSON(secrets.FTP_USERNAME) }}
88+
password: ${{ toJSON(secrets.FTP_PASSWORD) }}
89+
local-dir: ./out/_next/static/chunks/app/
90+
server-dir: ./_next/static/chunks/app/
91+
state-name: .ftp-deploy-sync-state.json
6492
6593
- name: Deploy site files to FTP
6694
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
67-
uses: SamKirkland/FTP-Deploy-Action@v4.3.6
95+
uses: Wandalen/wretry.action@v3.8.0
6896
with:
69-
server: ${{ secrets.FTP_HOST }}
70-
username: ${{ secrets.FTP_USERNAME }}
71-
password: ${{ secrets.FTP_PASSWORD }}
72-
local-dir: ./out/
73-
server-dir: ./
74-
exclude: |
75-
**/.git*
76-
**/.git*/**
77-
**/node_modules/**
78-
**/.DS_Store
79-
**/_next/**
80-
dry-run: false
97+
action: SamKirkland/FTP-Deploy-Action@v4.3.6
98+
attempt_limit: 3
99+
attempt_delay: 15000
100+
with: |
101+
server: ${{ toJSON(secrets.FTP_HOST) }}
102+
username: ${{ toJSON(secrets.FTP_USERNAME) }}
103+
password: ${{ toJSON(secrets.FTP_PASSWORD) }}
104+
local-dir: ./out/
105+
server-dir: ./
106+
exclude: |
107+
**/.git*
108+
**/.git*/**
109+
**/node_modules/**
110+
**/.DS_Store
111+
**/_next/**
112+
dry-run: false
81113

0 commit comments

Comments
 (0)