name: release
on:
  push:
    tags:
      - '*'

permissions:
  contents: read

jobs:
  release:
    permissions:
      contents: write  # for actions/create-release to create a release
    name: Create draft release
    runs-on: ubuntu-latest
    if: github.repository == 'mautic/mautic'

    outputs:
      mautic-version: ${{ steps.get-mautic-version.outputs.version }}
      is-prerelease: ${{ steps.is-prerelease.outputs.is-prerelease }}

    steps:
    - uses: actions/checkout@v4
      # Our build script needs access to all previous tags, so we add fetch-depth: 0
      with:
        fetch-depth: 0
    
    - name: Setup PHP, with composer and extensions
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.2
        extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql

    - name: Get tag name
      id: get-mautic-version
      run: echo "version=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT

    - name: Check if tag name matches version in release_metadata.json
      run: |
        METADATA_VERSION=$(jq -r '.version' app/release_metadata.json)

        if [[ "${{ steps.get-mautic-version.outputs.version }}" != "$METADATA_VERSION" ]]; then
          echo "❌ ERROR: tag name (${{ steps.get-mautic-version.outputs.version }}) doesn't match version in app/release_metadata.json ($METADATA_VERSION). Please ensure that both versions match!"
          exit 1
        else
          echo "✔ Tag name (${{ steps.get-mautic-version.outputs.version }}) and the version in app/release_metadata.json ($METADATA_VERSION) match. Great!"
        fi

    - name: Install dependencies
      run: |
        composer validate
        composer install --prefer-dist --no-progress --no-suggest

    - name: Get minimum Mautic version
      run: |
        echo "MAUTIC_MINIMUM_VERSION=$(jq -r '.minimum_mautic_version' app/release_metadata.json)" >> $GITHUB_ENV

    - name: "Download and extract minimum Mautic version: ${{ env.MAUTIC_MINIMUM_VERSION }}"
      run: |
        curl -sSL https://github.com/mautic/mautic/releases/download/${{ env.MAUTIC_MINIMUM_VERSION }}/${{ env.MAUTIC_MINIMUM_VERSION }}.zip -o ${{ env.MAUTIC_MINIMUM_VERSION }}.zip
        unzip -q ${{ env.MAUTIC_MINIMUM_VERSION }}.zip -d ./build/mautic-minimum-version

    - name: Build release files
      run: |
        php build/package_release.php -b=${{ steps.get-mautic-version.outputs.version }}
        echo 'MAUTIC_SHA1_CONTENTS<<EOF' >> $GITHUB_ENV
        cat build/packages/build-sha1-all >> $GITHUB_ENV
        echo 'EOF' >> $GITHUB_ENV

    - name: "Prerelease or not?"
      id: is-prerelease
      run: |
        STABILITY=$(jq -r '.stability' app/release_metadata.json)

        if [[ "${STABILITY}" == 'stable' ]]; then
          PRERELEASE=false
        else
          PRERELEASE=true
        fi

        echo "is-prerelease=${PRERELEASE}" >> $GITHUB_OUTPUT

    - name: Create Release
      id: create_release
      uses: actions/create-release@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: ${{ steps.get-mautic-version.outputs.version }}
        release_name: Mautic Community ${{ steps.get-mautic-version.outputs.version }}
        draft: true
        prerelease: ${{ steps.is-prerelease.outputs.is-prerelease }}
        body: |
          ${{ env.MAUTIC_CHANGELOG }}

          ${{ env.MAUTIC_SHA1_CONTENTS }}

    - name: Upload full package ${{ steps.get-mautic-version.outputs.version }}.zip
      uses: actions/upload-release-asset@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: ./build/packages/${{ steps.get-mautic-version.outputs.version }}.zip
        asset_name: ${{ steps.get-mautic-version.outputs.version }}.zip
        asset_content_type: application/zip

    - name: Upload update package ${{ steps.get-mautic-version.outputs.version }}-update.zip
      uses: actions/upload-release-asset@v1
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: ./build/packages/${{ steps.get-mautic-version.outputs.version }}-update.zip
        asset_name: ${{ steps.get-mautic-version.outputs.version }}-update.zip
        asset_content_type: application/zip

    - name: Store full package artifact
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.get-mautic-version.outputs.version }}.zip
        path: ./build/packages/${{ steps.get-mautic-version.outputs.version }}.zip

    - name: Store update package artifact
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.get-mautic-version.outputs.version }}-update.zip
        path: ./build/packages/${{ steps.get-mautic-version.outputs.version }}-update.zip

  test-fresh-install:
    name: Test a fresh installation
    needs: release
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
          MYSQL_DATABASE: mautictest
        ports:
          - 3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
    # We need this so we can get the local.php override file
    - uses: actions/checkout@v4

    - name: Setup PHP, with composer and extensions
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.2
        extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql

    - name: Download full installation package from previous step
      uses: actions/download-artifact@v4
      with:
        name: ${{ needs.release.outputs.mautic-version }}.zip

    - name: Install Mautic
      env:
        DB_PORT: ${{ job.services.mysql.ports[3306] }}
      run: |
        unzip -q ${{ needs.release.outputs.mautic-version }}.zip -d ./mautic-testing
        mkdir -p ./mautic-testing/var/logs
        cp ./.github/ci-files/local.php ./mautic-testing/config/local.php
        cd ./mautic-testing
        php bin/console mautic:install --force http://localhost

    - name: Store log artifacts
      if: ${{ always() }}
      uses: actions/upload-artifact@v4
      with:
        name: install-logs
        path: ./mautic-testing/var/logs/*

  test-update-install:
    name: Test updating from previous version
    needs: release
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
          MYSQL_DATABASE: mautictest
        ports:
          - 3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
      # We need this so we can get the local.php override file
    - uses: actions/checkout@v4

    - name: Get tag name and minimum Mautic version
      run: |
        echo "MAUTIC_MINIMUM_VERSION=$(jq -r '.minimum_mautic_version' app/release_metadata.json)" >> $GITHUB_ENV
        echo "MAUTIC_PHP_MINIMUM_VERSION=$(jq -r '.minimum_php_version' app/release_metadata.json)" >> $GITHUB_ENV

    - name: Setup PHP, with composer and extensions
      uses: shivammathur/setup-php@v2
      with:
        php-version: ${{ env.MAUTIC_PHP_MINIMUM_VERSION }}
        extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql

    - name: "Download and install minimum Mautic version: ${{ env.MAUTIC_MINIMUM_VERSION }}"
      env:
        DB_PORT: ${{ job.services.mysql.ports[3306] }}
      run: |
        curl -sSL https://github.com/mautic/mautic/releases/download/${{ env.MAUTIC_MINIMUM_VERSION }}/${{ env.MAUTIC_MINIMUM_VERSION }}.zip -o ${{ env.MAUTIC_MINIMUM_VERSION }}.zip
        unzip -q ${{ env.MAUTIC_MINIMUM_VERSION }}.zip -d ./mautic-testing
        mkdir -p ./mautic-testing/var/logs
        if [[ "$(jq -r '.version | .[0:1]' ./mautic-testing/app/release_metadata.json)" == "4" ]]; then
            cp ./.github/ci-files/local.php ./mautic-testing/app/config/local.php
        else
            cp ./.github/ci-files/local.php ./mautic-testing/config/local.php
        fi
        cd ./mautic-testing
        php bin/console mautic:install --force http://localhost
    
    - name: "Download update package artifact ${{ needs.release.outputs.mautic-version }}-update.zip"
      uses: actions/download-artifact@v4
      with:
        name: ${{ needs.release.outputs.mautic-version }}-update.zip
        path: ./mautic-testing

    - name: "Attempt update from ${{ env.MAUTIC_MINIMUM_VERSION }} to ${{ needs.release.outputs.mautic-version }}"
      env:
        DB_PORT: ${{ job.services.mysql.ports[3306] }}
      working-directory: ./mautic-testing
      run: |
        php bin/console mautic:update:apply --force --update-package=${{ needs.release.outputs.mautic-version }}-update.zip
        php bin/console mautic:update:apply --finish

    - name: Store log artifacts
      if: ${{ always() }}
      uses: actions/upload-artifact@v4
      with:
        name: update-logs
        path: ./mautic-testing/var/logs/*

  upload-release-asset:
    name: Upload release asset to m.mautic.org
    needs: [release, test-fresh-install, test-update-install]
    # We only want this job to run in Mautic's repo, not in forks
    if: github.repository_owner == 'mautic' && needs.release.outputs.is-prerelease
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup PHP, with composer and extensions
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.2
        extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql

    - name: Install dependencies
      working-directory: ./.github/workflows/mautic-asset-upload
      run: composer install --prefer-dist --no-progress

    - name: Download full installation package from previous step
      uses: actions/download-artifact@v4
      with:
        name: ${{ needs.release.outputs.mautic-version }}.zip

    # Category ID is 2 for Mautic release assets on m.mautic.org, that's why you're seeing "2" in the command below
    - name: Upload release asset ZIP to m.mautic.org
      run: |
        php ./.github/workflows/mautic-asset-upload/upload.php \
        https://m.mautic.org \
        "${{ secrets.MAUTIC_INSTANCE_USER }}" \
        "${{ secrets.MAUTIC_INSTANCE_PASSWORD }}" \
        "${{ needs.release.outputs.mautic-version }}" \
        4 \
        "${{ github.workspace }}/${{ needs.release.outputs.mautic-version }}.zip"
