name: Remote Deployment Pipeline on: push: branches: - main pull_request: types: [opened, synchronize, reopened, closed] env: REMOTE_DEPLOY_PATH: /tmp/app # Change to your remote deploy base path SSH_HOST: ${{ secrets.SSH_HOST }} SSH_USER: ${{ secrets.SSH_USER }} SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_PORT: ${{ secrets.SSH_PORT || 22 }} # Default to port 22 if not set jobs: prepare_deployment_vars: name: Prepare deployment vars runs-on: ubuntu-latest outputs: deploy_path: ${{ steps.set-vars.outputs.deploy_path }} steps: - name: Set deployment variables id: set-vars run: | if [[ "${{ github.event_name }}" == "pull_request" ]]; then DEPLOY_DIR_NAME="pr-${{ github.event.pull_request.number }}" else DEPLOY_DIR_NAME="main" fi echo "DEPLOY_PATH=${REMOTE_DEPLOY_PATH}/${DEPLOY_DIR_NAME}" >> $GITHUB_ENV echo "deploy_path=${REMOTE_DEPLOY_PATH}/${DEPLOY_DIR_NAME}" >> $GITHUB_OUTPUT echo "DEPLOY_PATH will be: ${REMOTE_DEPLOY_PATH}/${DEPLOY_DIR_NAME}" create_remote_directory: name: Create remote directory runs-on: ubuntu-latest needs: prepare_deployment_vars if: | (github.event_name == 'pull_request' && github.event.action != 'closed' && github.event.pull_request.merged == false) || github.ref == 'refs/heads/main' steps: - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ env.SSH_PRIVATE_KEY }} - name: Add host to known_hosts run: | mkdir -p ~/.ssh chmod 700 ~/.ssh echo "Scanning SSH host key for $SSH_HOST:$SSH_PORT..." ssh-keyscan -p "$SSH_PORT" -T 10 -H "$SSH_HOST" >> ~/.ssh/known_hosts 2>/dev/null || { echo "::error::Failed to ssh-keyscan $SSH_HOST:$SSH_PORT" exit 1 } chmod 644 ~/.ssh/known_hosts - name: Create directory on remote run: ssh -p "$SSH_PORT" $SSH_USER@$SSH_HOST "mkdir -p ${{ needs.prepare_deployment_vars.outputs.deploy_path }}" sync_repo_files: name: Sync repository files runs-on: ubuntu-latest needs: create_remote_directory if: | (github.event_name == 'pull_request' && github.event.action != 'closed' && github.event.pull_request.merged == false) || github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - name: asd run: ls -alh - name: Sync files via scp uses: appleboy/scp-action@master with: host: ${{ env.SSH_HOST }} username: ${{ env.SSH_USER }} key: ${{ env.SSH_PRIVATE_KEY }} port: ${{ env.SSH_PORT }} source: "./" target: "${{ needs.prepare_deployment_vars.outputs.deploy_path }}" debug: true # The 'exclude' parameter is supported and should be kept # exclude: | # .git/ # .github/ # node_modules/ run_docker_compose: name: Run docker-compose remotely runs-on: ubuntu-latest needs: sync_repo_files if: | (github.event_name == 'pull_request' && github.event.action != 'closed' && github.event.pull_request.merged == false) || github.ref == 'refs/heads/main' steps: - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ env.SSH_PRIVATE_KEY }} - name: Add host to known_hosts run: | mkdir -p ~/.ssh chmod 700 ~/.ssh echo "Scanning SSH host key for $SSH_HOST:$SSH_PORT..." ssh-keyscan -p "$SSH_PORT" -T 10 -H "$SSH_HOST" >> ~/.ssh/known_hosts 2>/dev/null || { echo "::error::Failed to ssh-keyscan $SSH_HOST:$SSH_PORT" exit 1 } chmod 644 ~/.ssh/known_hosts - name: Run docker-compose on remote host run: ssh -p "$SSH_PORT" $SSH_USER@$SSH_HOST "cd ${{ needs.prepare_deployment_vars.outputs.deploy_path }} && docker-compose up -d --build" cleanup_mr_environment: name: Cleanup MR environment runs-on: ubuntu-latest needs: prepare_deployment_vars if: | github.event_name == 'pull_request' && (github.event.action == 'closed' || github.event.pull_request.merged == true) steps: - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ env.SSH_PRIVATE_KEY }} - name: Add host to known_hosts run: | mkdir -p ~/.ssh chmod 700 ~/.ssh echo "Scanning SSH host key for $SSH_HOST:$SSH_PORT..." ssh-keyscan -p "$SSH_PORT" -T 10 -H "$SSH_HOST" >> ~/.ssh/known_hosts 2>/dev/null || { echo "::error::Failed to ssh-keyscan $SSH_HOST:$SSH_PORT" exit 1 } chmod 644 ~/.ssh/known_hosts - name: Delete deployment directory run: | ssh -p "$SSH_PORT" $SSH_USER@$SSH_HOST "if [ -d '${{ needs.prepare_deployment_vars.outputs.deploy_path }}' ]; then rm -rf '${{ needs.prepare_deployment_vars.outputs.deploy_path }}'; echo 'Directory removed.'; else echo 'Directory not found, skipping.'; fi"