'TYPO3: How to publish an extension to TER with Github actions and tailor and add third party library on the fly

I would like to publish an extension automatically to TER by using the Github actions and tailor, the CLI Tool for maintaining public TYPO3 Extensions . This works perfectly fine with the following workflow configuration:

name: TYPO3 Extension TER Release

on:
  push:
    tags:
      - '*'
jobs:
  publish:
    name: Publish new version to TER
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-20.04
    env:
      TYPO3_EXTENSION_KEY: ${{ secrets.TYPO3_EXTENSION_KEY }}
      TYPO3_API_TOKEN: ${{ secrets.TYPO3_API_TOKEN }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Check tag
        run: |
          if ! [[ ${{ github.ref }} =~ ^refs/tags/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then
            exit 1
          fi

      - name: Get version
        id: get-version
        run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//}

      - name: Get comment
        id: get-comment
        run: |
          readonly local comment=$(git tag -n10 -l ${{ steps.get-version.outputs.version }} | sed "s/^[0-9.]*[ ]*//g")

          if [[ -z "${comment// }" ]]; then
            echo ::set-output name=comment::Released version ${{ steps.get-version.outputs.version }} of ${{ env.TYPO3_EXTENSION_KEY }}
          else
            echo ::set-output name=comment::$comment
          fi

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 7.4
          extensions: intl, mbstring, json, zip, curl
          tools: composer:v2

      - name: Install tailor
        run: composer global require typo3/tailor --prefer-dist --no-progress --no-suggest

      - name: Publish to TER
        run: php ~/.composer/vendor/bin/tailor ter:publish --comment "${{ steps.get-comment.outputs.comment }}" ${{ steps.get-version.outputs.version }}

Since my extension depends on a third party PHP library (which is loaded if the extension is installed with composer) I need to add this library on the fly, when the extension gets deployed to the TER. Therefore I added in Resources/Private/PHP/ a composer.json and a composer.lock.

Now I would like to tell tailor to execute composer install in Resources/Private/PHP/ and package the extension including the external library. Is this possible? If so, how?



Solution 1:[1]

Generally it is useful to put everything in Composer command scripts so that you are actually able to execute actions without depending on Github actions or a CI in general.

For example you could add a few commands like this:

{
    "scripts": {
        "build:cleanup": [
            "git reset --hard",
            "git clean -xfd"
        ],
        "deploy:ter:setup": [
            "@composer global require clue/phar-composer typo3/tailor"
        ],
        "build:ter:vendors": [
            "(mkdir -p /tmp/vendors && cd /tmp/vendors && composer require acme/foo:^1.0 acme/bar:^2.0 && composer global exec phar-composer build -v)",
            "cp /tmp/vendors/vendors.phar ./Resources/Private/libraries.phar",
            "echo \"require 'phar://' . \\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility::extPath('$(composer config extra.typo3/cms.extension-key)') . 'Resources/Private/libraries.phar/vendor/autoload.php';\" >> ext_localconf.php"
        ],
        "deploy:ter:upload": [
            "composer global exec -v -- tailor ter:publish --comment \"$(git tag -l --format='%(contents)' $TAG)\" $TAG"
        ],
        "deploy:ter": [
            "@build:cleanup",
            "@deploy:ter:setup",
            "@build:ter:vendors",
            "@deploy:ter:upload"
        ]
    }
}

The various scripts explained:

  • build:cleanup drops all pending files to ensure no undesired files are uploaded to the TER
  • build:ter:setup installs typo3/tailor for the TER upload and clue/phar-composer for building a Phar of your vendor dependencies
  • build:ter:vendors installs a manually maintained list of dependencies in a temporary directory and builds a Phar from that; it then copies that Phar to the current directory and adds a require call to your ext_localconf.php
  • deploy:ter:upload finally invokes Tailor to upload the current directory including the Phar and the ext_localconf.php adjustment and fetches the comment of the specified Git tag; notice that tagging should be done with --message here to have an annotated Git tag (e.g. git tag -a 1.2.3 -m "Bugfix release")

Now assuming you export/provide the environment variables TYPO3_API_USERNAME, TYPO3_API_PASSWORD and TAG you can instantly deploy the latest release like this:

# Provide username and password for TER, if not done yet
export TYPO3_API_USERNAME=YourName
export TYPO3_API_PASSWORD=YourSecretPassword

# Provide the tag to deploy
TAG=1.2.3 composer deploy:ter

Subsequently the related Github action becomes very simple:

jobs:
  build:
    # ...

  release-ter:
    name: TYPO3 TER release

    if: startsWith(github.ref, 'refs/tags/')
    needs: build

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Deploy to TER
        env:
          TYPO3_API_USERNAME: ${{secrets.TYPO3_API_USERNAME}}
          TYPO3_API_PASSWORD: ${{secrets.TYPO3_API_PASSWORD}}
          TAG: ${{github.ref_name}}
        run: composer deploy:ter

Here is a live example:

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1