Skip to content

Nuxt.js Project GitHub Actions Automated CI/CD Practice (Part 3): Email Notifications ​

Nuxt.js Project GitHub Actions Automated CI/CD Practices (Part 3): Email Notification Diagram

Preface ​

Following the previous two articles, we have implemented automatic building, packaging, and deployment when a Release is created, and restarting the service via PM2. This article will explain How to configure email notifications, enabling the team to receive timely email notifications when CI/CD executions succeed or fail, achieving full-process awareness.

Review of this series of articles:

PartGoalStatus
Part OneBuild, package, and upload to GitHub Release✅ Completed
Part TwoAutomatically deploy to a remote server and restart the service with PM2✅ Completed
Part Three (Main Text)CI/CD Email Notifications📍 Current

Achieved effect:

After you create a Release, the entire process will run fully automatically and send email notifications at the following points:

  • Build succeeded → received success email

  • Build failed → Alert email received (with error log link)

  • Deployment successful → Success email received (including access URL)

  • Deployment failed → alert email received (requires immediate inspection)

The entire process requires no manual intervention, truly achieving One-click release, automatic deployment, real-time awareness.

NOTICE

This article is Part three of the series, focusing on the CI/CD email notification stage. It is recommended to complete the configuration in the first two parts before continuing with this article.

Part Three Objectives ​

Automatically send email notifications at key points in the CI/CD process:

  • Build success/failure notification

  • Deployment success/failure notification

  • The email content includes the version, trigger, time, and details link.

  • The deployment success email includes the access address.

Directory structure (continued from the first two parts) ​

.github/
└── workflows/
    └── release-bump.yaml   # Complete workflow including build, deployment, and notification

Complete configuration file ​

Building on the previous two parts, add an email notification step:

yaml
name: Auto Bump Version on Release

on:
  release:
    types: [created]

jobs:
  # Job 1: Build and release
  build-and-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    outputs:
      version: ${{ steps.extract-version.outputs.version }}
      project_name: ${{ steps.project-name.outputs.project_name }}

    steps:
      # ... the first 14 steps (checkout, install dependencies, build, package, upload, etc.) ...

      # 15. Build success email
      - name: Send build success email
        if: success()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: ✅ Nuxt build successful - ${{ github.repository }}
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🎉 Nuxt project built successfully!

            Repository: ${{ github.repository }}
            Version: ${{ steps.extract-version.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ✅ Success

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

      # 16. Build failure email
      - name: Send build failure email
        if: failure()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "❌ Nuxt Build Failed - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🚨 Nuxt project build failed, please check immediately!

            Repository: ${{ github.repository }}
            Version: ${{ steps.extract-version.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ❌ Failed

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
            Please click the link above to view detailed error information.

  # Job 2: Remote deployment
  remote-deploy:
    runs-on: ubuntu-latest
    needs: build-and-release
    if: github.event_name == 'release' && success()
    permissions:
      actions: read

    steps:
      # ... the first 6 steps (download, extraction, SCP transfer, SSH deployment, etc.) ...

      # 7. Deployment success email
      - name: Send deploy success email
        if: success()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "✅ Nuxt Deployment Successful - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🎉 Nuxt project deployed successfully!

            Repository: ${{ github.repository }}
            Version: ${{ needs.build-and-release.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ✅ Success

            🌐 Access URL: ${{ vars.DEPLOY_WEBSITE_DOMAIN }}
            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

      # 8. Deployment failure email
      - name: Send deploy failure email
        if: failure()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "❌ Nuxt Deployment Failed - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🚨 Nuxt project deployment failed, please check immediately!

            Repository: ${{ github.repository }}
            Version: ${{ needs.build-and-release.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ❌ Failed

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
            Please click the link above to view detailed error information.

Required Secrets and Variables configuration ​

In the GitHub repository's Settings -> Secrets and variables -> Actions Add to:

Secrets (Sensitive Information) ​

Secret NameDescriptionExample
GMAIL_SMTP_PASSWORDGmail SMTP password (app-specific password)xxxxxxxxxxxx
ACCESS_TOKENGitHub Personal Access Token (used for uploading a Release)github_pat_xxx
DEPLOY_HOSTServer IP or domain name192.168.1.100
DEPLOY_USERSSH login usernameroot or ubuntu
DEPLOY_SSH_KEYSSH private key content-----BEGIN OPENSSH PRIVATE KEY-----

Variables (non-sensitive configuration) ​

Variable nameExplanationExample
GMAIL_SMTP_USERGmail email address[email protected]
NOTIFY_EMAILSNotification email list (separate multiple addresses with commas)[email protected],[email protected]
DEPLOY_WEBSITE_DOMAINDeployed website domain namehttps://example.com
DEPLOY_PORTSSH Port (Optional)22

How to get a Gmail app-specific password ​

  • Log in to your Gmail account

  • Enter Google 账号→安全性→两步验证(Must be enabled)

  • Enter 应用专用密码

  • Select app:邮件, Equipment:GitHub Actions

  • Generate a 16-character password, copy and save.

⚠️Attention: Gmail regular passwords cannot be used for SMTP; an app-specific password must be used.

Detailed Explanation of Key Steps ​

1. Conditional trigger ​

yaml
- name: Send build success email
  if: success()
  • if: success(): Execute only when the previous step succeeds

  • if: failure(): Execute only when the previous step fails

  • Ensure that notifications are received for both success and failure.

2. Email configuration ​

yaml
with:
  server_address: smtp.gmail.com   # Gmail SMTP server
  server_port: 587                 # TLS port
  username: ${{ vars.GMAIL_SMTP_USER }}      # Sender email (Variable)
  password: ${{ secrets.GMAIL_SMTP_PASSWORD }} # SMTP Password (Secret)
  to: ${{ vars.NOTIFY_EMAILS }}    # Recipient List (Variable)
  from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"

Why use Variable instead of Secret?

  • Email addresses and recipient lists are not sensitive information, so Variable can be used.

  • The SMTP password is sensitive information and must use a Secret.

3. Dynamic email content ​

yaml
body: |
  🎉 Nuxt project built successfully!

  Repository: ${{ github.repository }}
  Version: ${{ steps.extract-version.outputs.version }}
  Triggered by: ${{ github.actor }}
  Time: ${{ github.event.repository.updated_at }}
  Status: ✅ Success

  Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

GitHub Context Description:

ContextDescriptionExample
github.repositoryWarehouse Nameowner/repo
github.actorTriggeroperator-username
github.run_idRun ID26586293547
github.server_urlGitHub server addresshttps://github.com
github.event.repository.updated_atRelease update time2026-05-28T16:00:00Z

4. Multiple Recipients Support ​

yaml
to: ${{ vars.NOTIFY_EMAILS }}

NOTIFY_EMAILS Supports multiple formats:

bash
# single mailbox
[email protected]

# Multiple email addresses (comma-separated)
[email protected],[email protected],[email protected]

# Multiple email addresses with names
"Admin <[email protected]>,Tech Lead <[email protected]>"

5. Distinguishing Between Build and Deployment Notifications ​

Notification typeSuccess ThemeFailure themeUnique field
Build✅ Nuxt build successful❌ Nuxt build failedNone
Deployment✅ Nuxt deployment successful❌ Nuxt deployment failedAccess address

Operating process ​

  • Create a new Release in a GitHub repository

  • Part One: Automated build, packaging, and upload

  • Build successful → Send Build success email

  • Build failed → send Build failure email(including log link)

  • Part Two: Automatic deployment (executed only when the build succeeds)

  • Deployment successful → Send Deployment Success Email(including access address)

  • Deployment failed → Send Deployment failure email(Immediate inspection required)

Frequently Asked Questions ​

Q: Email sending failed, prompting "At least one of 'to', 'cc' or 'bcc' must be specified"? ​

A:NOTIFY_EMAILS Variable is not configured or its value is empty. Check:

  • Whether the Variable name is correct (case-sensitive)

  • Whether the Variable value is a valid email

  • After adding the Variable, rerun the workflow.

Q: Gmail SMTP authentication failed, showing "Username and Password not accepted"? ​

A: Possible causes and solutions:

  • App-specific password not used:Generate an app-specific password

  • The account does not have two-step verification enabled: it must be enabled first.

  • Password copy incomplete: regenerate and copy

Q: How do you test whether the email configuration is correct? ​

A: We can temporarily add a test step:

yaml
- name: Test email
  uses: dawidd6/action-send-mail@v3
  with:
    server_address: smtp.gmail.com
    server_port: 587
    username: ${{ vars.GMAIL_SMTP_USER }}
    password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
    subject: "Test email from GitHub Actions"
    to: ${{ vars.NOTIFY_EMAILS }}
    from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
    body: |
      This is a test email to verify SMTP configuration.

Q: Can I use other email service providers (such as Outlook, QQ Mail)? ​

A: Yes, modify the following configuration:

yaml
# Outlook
server_address: smtp-mail.outlook.com
server_port: 587

# QQ Mail
server_address: smtp.qq.com
server_port: 587

You also need to obtain the SMTP authorization code from the corresponding service provider.

Summary ​

This article completes the third part of the series—email notifications. By configuring GitHub Actions, we have implemented:

  • Automatically send email notifications on build success/failure

  • Automatically send email notifications on deployment success/failure

  • The deployment success email includes the access address.

  • Failure email contains error log link

At this point, the complete CI/CD pipeline has been fully connected:

Create Release
    ↓
Automatic build → Send build notification
    ↓
Auto-build → Upload Release
    ↓
Automatic deployment → PM2 restart
    ↓
Send deployment notification (including access address)

Series Article Retrospective ​

articlecontentstate
Part OneBuild and release automation✅ Completed
Part TwoRemote deployment automation✅ Completed
Part Three (This Article)Email notification✅ Completed

Three articles, building a complete CI/CD pipeline for a Nuxt.js project from scratch!

💡 Confirmation point

After running this workflow, the inbox should receive two emails: a build notification and a deployment notification. The deployment success email should contain the correct access URL.

Attachment ​

For your convenience in viewing the complete release-bump.yaml Configuration file. The complete content is provided below for reference:

Click to view the complete configuration file release-bump.yaml
yaml
name: Auto Bump Version on Release

on:
  release:
    types: [created]  # Trigger only when a new Release is created

jobs:
  # Job 1: Build and release
  build-and-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write  # Allow pushing code and creating Releases
    outputs:
      version: ${{ steps.extract-version.outputs.version }}
      project_name: ${{ steps.project-name.outputs.project_name }} # Pass to the subsequent deployment Job

    steps:
      # 1. Check out the code
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.release.target_commitish }}
          fetch-depth: 0

      # 2. Install pnpm
      - name: Install pnpm
        uses: pnpm/action-setup@v4

      # 3. Set up Node.js
      - name: Setup Node.js
        uses: actions/setup-node@v5
        with:
          node-version: 20
          cache: 'pnpm'

      # 4. Install dependencies
      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      # 5. Code Review
      - name: Lint
        run: pnpm run lint

      # 6. Type checking
      - name: Typecheck
        run: pnpm run typecheck

      # 7. Extract version number
      - name: Extract Version
        id: extract-version
        run: |
          TAG=${GITHUB_REF#refs/tags/}
          VERSION=$(echo "$TAG" | sed 's/^v//')
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      # 8. Extract the project name (dynamically retrieved from package.json)
      - name: Extract Project Name
        id: project-name
        run: |
          PROJECT_NAME=$(node -p "require('./package.json').name")
          echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT

      # 9. Update the package.json version number
      - name: Update Version
        run: |
          pnpm version ${{ steps.extract-version.outputs.version }} --no-git-tag-version
          cat package.json | grep version

      # 10. Build a Nuxt.js project
      - name: Build Nuxt.js
        env:
          NODE_OPTIONS: "--max-old-space-size=4096"
        run: pnpm run build

      # 11. Create a compressed package (using a dynamic project name)
      - name: Create Distribution Archive
        run: |
          if [ ! -d ".output" ]; then
            echo "Error: .output directory not found!"
            exit 1
          fi

          echo "Contents of .output directory:"
          ls -la .output/

          PROJECT_NAME="${{ steps.project-name.outputs.project_name }}"
          VERSION="${{ steps.extract-version.outputs.version }}"

          tar -czf ${PROJECT_NAME}-${VERSION}.tar.gz -C .output .
          cd .output && zip -r ../${PROJECT_NAME}-${VERSION}.zip . && cd ..

          echo "Archive created successfully!"
          ls -la *.tar.gz *.zip

      # 12. Upload to GitHub Release
      - name: Upload Release Assets
        uses: ncipollo/release-action@v1
        with:
          artifacts: "./${{ steps.project-name.outputs.project_name }}-${{ steps.extract-version.outputs.version }}.tar.gz,./${{ steps.project-name.outputs.project_name }}-${{ steps.extract-version.outputs.version }}.zip"
          allowUpdates: true
          omitBody: true
          omitName: true
          token: ${{ secrets.ACCESS_TOKEN }}
          makeLatest: "true"  # Uploading assets will not break the Release's latest property.

      # 13. Upload build artifacts for use by subsequent Jobs
      - name: Upload Build Artifact
        uses: actions/upload-artifact@v7
        with:
          name: build-output
          path: ${{ steps.project-name.outputs.project_name }}-${{ steps.extract-version.outputs.version }}.tar.gz
          retention-days: 1
          if-no-files-found: error
          overwrite: true

      # 14. Commit version number change
      - name: Commit Changes
        run: |
          git config user.name "GitHub Actions"
          git config user.email "[email protected]"
          git add package.json pnpm-lock.yaml
          git commit -m "chore(release): bump to ${{ steps.extract-version.outputs.version }} [skip ci]"
          git push origin HEAD:${{ github.event.release.target_commitish }}

      # 15. Build success email
      - name: Send build success email
        if: success()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: ✅ Nuxt build successful - ${{ github.repository }}
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🎉 Nuxt project built successfully!

            Repository: ${{ github.repository }}
            Version: ${{ steps.extract-version.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ✅ Success

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

      # 16. Build failure email
      - name: Send build failure email
        if: failure()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "❌ Nuxt Build Failed - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🚨 Nuxt project build failed, please check immediately!

            Repository: ${{ github.repository }}
            Version: ${{ steps.extract-version.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ❌ Failed

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
            Please click the link above to view detailed error information.

  # Job 2: Remote deployment
  remote-deploy:
    runs-on: ubuntu-latest
    needs: build-and-release  # Waiting for build to complete
    if: github.event_name == 'release' && success()
    permissions:
      actions: read  # Allow downloading artifacts

    steps:
      # 1. Download build artifacts
      - name: Download Artifact
        uses: actions/download-artifact@v8
        with:
          name: build-output
          path: ./

      # 2. Extract artifact
      - name: Extract Artifact
        run: |
          echo "Contents before extract:"
          ls -la
          echo ""
          echo "Extracting tar.gz..."
          # Extract directly to the current directory, including the nitro.json file and the public and server directories.
          tar -xzf ${{ needs.build-and-release.outputs.project_name }}-${{ needs.build-and-release.outputs.version }}.tar.gz
          echo "Extracted contents:"
          ls -la
          echo "Total files: $(find . -maxdepth 1 -type f | wc -l)"

      # 3. Verify the extracted content
      - name: Verify Extracted Content
        run: |
          if [ ! -f "nitro.json" ]; then
            echo "ERROR: nitro.json not found after extraction!"
            exit 1
          fi
          echo "✅ Artifact extracted successfully"

      # 4. SCP transfer to the server (transfer all files in the current directory)
      - name: Deploy to Server
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_SSH_KEY }}
          port: ${{ secrets.DEPLOY_PORT || 22 }}
          source: "./"  # Transfer all contents in the current directory
          target: "/tmp/${{ needs.build-and-release.outputs.project_name }}-build-${{ needs.build-and-release.outputs.version }}/"

      # 5. SSH remote deployment execution
      - name: Execute Remote Deployment
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_SSH_KEY }}
          port: ${{ secrets.DEPLOY_PORT || 22 }}
          script: |
            set -e  # Exit immediately upon error

            PROJECT_NAME="${{ needs.build-and-release.outputs.project_name }}"
            VERSION="${{ needs.build-and-release.outputs.version }}"
            DEPLOY_DIR="/var/www/${PROJECT_NAME}"
            BUILD_DIR="/tmp/${PROJECT_NAME}-build-${VERSION}"

            echo "=========================================="
            echo "Deploying ${PROJECT_NAME} version ${VERSION}"
            echo "=========================================="

            # 1. Back up the current version
            if [ -d "$DEPLOY_DIR" ]; then
              BACKUP_DIR="/var/www/${PROJECT_NAME}-backup-$(date +%Y%m%d_%H%M%S)"
              echo "📦 Creating backup: ${BACKUP_DIR}"
              cp -r "$DEPLOY_DIR" "$BACKUP_DIR"
              # Keep the latest 5 backups
              ls -t /var/www/${PROJECT_NAME}-backup-* 2>/dev/null | tail -n +6 | xargs rm -rf || true
            else
              echo "📁 Creating deployment directory: ${DEPLOY_DIR}"
              mkdir -p "$DEPLOY_DIR"
            fi

            # 2. Deploy new files
            # Note: After extraction, the files are directly under BUILD_DIR; there is no .output layer.
            echo "📤 Deploying files..."
            rm -rf ${DEPLOY_DIR}/*
            cp -r ${BUILD_DIR}/* ${DEPLOY_DIR}/

            # 3. Set permissions
            chown -R www-data:www-data ${DEPLOY_DIR}
            chmod -R 755 ${DEPLOY_DIR}

            # 4. Restart the PM2 service
            echo "🔄 Restarting PM2 service..."
            pm2 restart ${PROJECT_NAME}

            # 5. Clean up temporary files
            echo "🧹 Cleaning up..."
            rm -rf ${BUILD_DIR}

            # 6. Display the deployment result
            echo "=========================================="
            echo "✅ Deployment completed successfully!"
            echo "📍 Deployed to: ${DEPLOY_DIR}"
            echo "📌 Version: ${VERSION}"
            echo "=========================================="
            pm2 status ${PROJECT_NAME}

      # 6. Output Deployment Overview
      - name: Build Summary
        run: |
          echo "=========================================="
          echo "🎉 DEPLOYMENT SUMMARY"
          echo "=========================================="
          echo "Project: ${{ needs.build-and-release.outputs.project_name }}"
          echo "Version: ${{ needs.build-and-release.outputs.version }}"
          echo "Status: ${{ job.status }}"
          echo ""
          echo "📊 Directory Statistics:"
          echo "  JSON files (root): $(find . -maxdepth 1 -type f -name "*.json" | wc -l) files"
          echo "  Total directories (root): $(find . -maxdepth 1 -type d | wc -l) directories"
          echo ""
          echo "🔍 Key Files Check:"
          echo "  nitro.json: $([ -f "nitro.json" ] && echo '✅ YES' || echo '❌ NO')"
          echo "  public/: $([ -d "public" ] && echo '✅ EXISTS' || echo '❌ NOT FOUND')"
          echo "  server/: $([ -d "server" ] && echo '✅ EXISTS' || echo '❌ NOT FOUND')"
          echo ""
          echo "⏱️  Time: $(date)"
          echo "=========================================="

      # 7. Deployment success email
      - name: Send deploy success email
        if: success()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "✅ Nuxt Deployment Successful - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🎉 Nuxt project deployed successfully!

            Repository: ${{ github.repository }}
            Version: ${{ needs.build-and-release.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ✅ Success

            🌐 Access URL: ${{ vars.DEPLOY_WEBSITE_DOMAIN }}
            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

      # 8. Deployment failure email
      - name: Send deploy failure email
        if: failure()
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.gmail.com
          server_port: 587
          username: ${{ vars.GMAIL_SMTP_USER }}
          password: ${{ secrets.GMAIL_SMTP_PASSWORD }}
          subject: "❌ Nuxt Deployment Failed - ${{ github.repository }}"
          to: ${{ vars.NOTIFY_EMAILS }}
          from: "GitHub Actions <${{ vars.GMAIL_SMTP_USER }}>"
          body: |
            🚨 Nuxt project deployment failed, please check immediately!

            Repository: ${{ github.repository }}
            Version: ${{ needs.build-and-release.outputs.version }}
            Triggered by: ${{ github.actor }}
            Time: ${{ github.event.repository.updated_at }}
            Status: ❌ Failed

            Details: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
            Please click the link above to view detailed error information.

Series navigation ​

Conclusion ​

Through the series of articles titled Nuxt.js Project GitHub Actions Automated CI/CD Practice, we completed a full closed loop of build, deployment, and notification in GitHub Actions. We hope this is helpful to you, and we also hope you can extrapolate from it and apply these practices to projects in other languages or of other types.

Thank you for reading!

Last updated on11/07/2026, 02:16 PM
@fishfinal | @fishfinals | [email protected]