fix(ci): update Woodpecker deploy step
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
rafael.gonzalez.albes 2026-07-15 10:42:29 +00:00
parent 6c2545a713
commit 33e9933d93
2 changed files with 112 additions and 0 deletions

62
deploy.js Normal file
View file

@ -0,0 +1,62 @@
import Client from 'ssh2-sftp-client';
import path from 'path';
const sftp = new Client();
const config = {
host: process.env.SFTP_HOST,
port: parseInt(process.env.SFTP_PORT || '22', 10),
username: process.env.SFTP_USER,
password: process.env.SFTP_PASSWORD
};
const localDir = path.resolve('./dist');
const remoteDir = 'dist';
async function main() {
if (!config.host || !config.username || !config.password) {
console.error('Error: Missing SFTP credentials in the .env file.');
console.error('Please create a .env file with SFTP_HOST, SFTP_USER, and SFTP_PASSWORD variables.');
process.exit(1);
}
console.log(`Connecting to SFTP server ${config.host} as ${config.username}...`);
try {
await sftp.connect(config);
console.log('Successfully connected! Uploading files recursively...');
// Upload local dist folder recursively to remote home folder
await sftp.uploadDir(localDir, remoteDir);
console.log('Upload complete! Applying correct server permissions...');
// Set folder permissions relative to dist/ on server
await sftp.chmod('dist', 0o755);
await sftp.chmod('dist/.htaccess', 0o644);
await sftp.chmod('dist/index.html', 0o644);
try {
await sftp.chmod('dist/assets', 0o755);
const list = await sftp.list('dist/assets');
for (const item of list) {
await sftp.chmod(`dist/assets/${item.name}`, 0o644);
}
// Fix permissions for local flag images
await sftp.chmod('dist/flags', 0o755);
const flags = await sftp.list('dist/flags');
for (const item of flags) {
await sftp.chmod(`dist/flags/${item.name}`, 0o644);
}
console.log('Folder permissions applied successfully (dist -> 755, assets -> 755, flags -> 755, files -> 644).');
} catch (err) {
console.log('Note: Some assets file permissions could not be set automatically, but parent directory is open.');
}
console.log('Deployment completed successfully! Website is now fully live.');
} catch (err) {
console.error('Deployment failed:', err.message);
} finally {
await sftp.end();
}
}
main();

50
woodpecker.yml Normal file
View file

@ -0,0 +1,50 @@
# Woodpecker CI/CD — portfolio → rafaelgonzalezalbes.com
# Secrets: sftp_host, sftp_user, sftp_pass, sftp_remote_path (= dist)
when:
- event: [push, pull_request]
steps:
install:
image: node:22-alpine
commands:
- npm ci
lint:
image: node:22-alpine
depends_on: [install]
commands:
- npm run lint
build:
image: node:22-alpine
depends_on: [lint]
commands:
- npm run build
- node check-qa.cjs
deploy:
image: alpine:3.20
depends_on: [build]
environment:
SFTP_HOST:
from_secret: sftp_host
SFTP_USER:
from_secret: sftp_user
SFTP_PASS:
from_secret: sftp_pass
REMOTE_PATH:
from_secret: sftp_remote_path
commands:
- apk add --no-cache lftp
- |
lftp <<EOF
set sftp:auto-confirm yes
set net:password "$SFTP_PASS"
open -u "$SFTP_USER" sftp://$SFTP_HOST
mirror -R dist/ $REMOTE_PATH --delete --verbose
bye
EOF
when:
- event: push
branch: main