Rudy is me

A weblog (mostly) about PHP and TYPO3 development

Automatically deploy extension from Github to TYPO3 extension repository

Many TYPO3 extensions use Github as version control system. With Github Actions and TYPO3 Tailor it is possible to automatically deploy your extension to the TYPO3 extension repository every time you create a new release.

The first thing you need to do to set this up is create an access token in the TYPO3 extension repository. This token is needed to give the Github Action access to the TYPO3 extension repository to upload a new version of the extension.

  • Login in to extensions.typo3.org with the user that manages the extension key.
  • In the top menu, click on "My access tokens".
  • Create a new access token.
    • The access token name is just a description. Use something logical, like "Github deploy for [extension name]".
    • Expiration date can be set to a maximum of a year from now. Right now there is no reminder when the token is expiring, so you'll need to keep track of this yourself (or check it if the deploy fails).
    • Scope should be set to "extension:read" and "extension:write".
    • You can use the access key for multiple extensions. Just select the ones you want to use it for.
  • After clicking on the "Create access token" button, it will generate the access token and an update token. Save both in a secure location. If you lose them, you will need to generate a new token.

Next you need to setup the Github Action in the extension repository.

  • Go to the Github repository of the extension and log in with an account that has admin rights for that repository.
  • In the top menu, click on "Settings".
  • In the side menu, click on "Secrets". Here we'll add one or two variables the Action will need. These variables are encrypted and can not be viewed after creation, so you don't have to worry about the access token being visible.
    • TYPO3_API_TOKEN. This should be set to the access token you created earlier.
    • TYPO3_EXTENSION_KEY. This should be the extension key. If the extension's composer.yaml has the [extra][typo3/cms][extension-key] set to the extension key (which it should have) this variable does not need to be set.
  • On the master branch of your extension repository, create the file .github/workflows/ter-release.yml with the following content:
name: TYPO3 extension TER publish
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 }}

That's it. This will deploy your extension automatically every time you create a release with the tag x.y.z (for example 1.0.2).