Automate the release workflow using GitHub actions
This introduces a two-part release mechanism. A manually triggered workflow asks for the important info like type of release (stable, rc) and code name. It then creates a cleanly mergable pull request. When that pull request is merged, a release is automatically tagged, built and uploaded. Another workflow is introduced to keep track of the deleted.files info. This is one less chore to do on a release. A new scheme for tags is also introduced, making all tags sortable, regardless of their type. They follow the pattern release-YYYY-MM-DD(<hotfixletter>|rc) A script will be used to clean-up the existing tags.
This commit is contained in:
parent
a42c05d2dd
commit
290ea73da0
|
@ -10,6 +10,9 @@ charset = utf-8
|
|||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[{vendor,inc/phpseclib}/**]
|
||||
; Use editor default (possible autodetection).
|
||||
indent_style =
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*.ico binary
|
||||
*.xcf binary
|
||||
|
||||
.git export-ignore
|
||||
.gitattributes export-ignore
|
||||
.github export-ignore
|
||||
.gitignore export-ignore
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
if (!defined('DOKU_INC')) define('DOKU_INC', __DIR__ . '/../');
|
||||
require_once(DOKU_INC . 'vendor/autoload.php');
|
||||
require_once DOKU_INC . 'inc/load.php';
|
||||
|
||||
/**
|
||||
* Command Line utility to gather and check data for building a release
|
||||
*/
|
||||
class Release extends splitbrain\phpcli\CLI
|
||||
{
|
||||
// base URL to fetch raw files from the stable branch
|
||||
protected $BASERAW = 'https://raw.githubusercontent.com/splitbrain/dokuwiki/stable/';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function __construct($autocatch = true)
|
||||
{
|
||||
parent::__construct($autocatch);
|
||||
|
||||
$this->error(print_r($_ENV, true));
|
||||
|
||||
// when running on a clone, use the correct base URL
|
||||
$repo = getenv('GITHUB_REPOSITORY');
|
||||
if ($repo) {
|
||||
$this->BASERAW = 'https://raw.githubusercontent.com/' . $repo . '/stable/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function setup(\splitbrain\phpcli\Options $options)
|
||||
{
|
||||
$options->setHelp('This tool is used to gather and check data for building a release');
|
||||
|
||||
$options->registerCommand('new', 'Get environment for creating a new release');
|
||||
$options->registerOption('type', 'The type of release to build', null, 'stable|hotfix|rc', 'new');
|
||||
$options->registerOption('date', 'The date to use for the version. Defaults to today', null, 'YYYY-MM-DD', 'new');
|
||||
$options->registerOption('name', 'The codename to use for the version. Defaults to the last used one', null, 'codename', 'new');
|
||||
|
||||
$options->registerCommand('current', 'Get environment of the current release');
|
||||
}
|
||||
|
||||
protected function main(\splitbrain\phpcli\Options $options)
|
||||
{
|
||||
switch ($options->getCmd()) {
|
||||
case 'new':
|
||||
$this->prepareNewEnvironment($options);
|
||||
break;
|
||||
case 'current':
|
||||
$this->prepareCurrentEnvironment($options);
|
||||
break;
|
||||
default:
|
||||
echo $options->help();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare environment for the current branch
|
||||
*/
|
||||
protected function prepareCurrentEnvironment(\splitbrain\phpcli\Options $options)
|
||||
{
|
||||
$current = $this->getLocalVersion();
|
||||
// we name files like the string in the VERSION file, with rc at the front
|
||||
$current['file'] = ($current['type'] === 'rc' ? 'rc' : '') . $current['date'] . $current['hotfix'];
|
||||
|
||||
// output to be piped into GITHUB_ENV
|
||||
foreach ($current as $k => $v) {
|
||||
echo "current_$k=$v\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare environment for creating a new release
|
||||
*/
|
||||
protected function prepareNewEnvironment(\splitbrain\phpcli\Options $options)
|
||||
{
|
||||
$current = $this->getUpstreamVersion();
|
||||
|
||||
// continue if we want to create a new release
|
||||
$next = [
|
||||
'type' => $options->getOpt('type'),
|
||||
'date' => $options->getOpt('date'),
|
||||
'codename' => $options->getOpt('name'),
|
||||
'hotfix' => '',
|
||||
];
|
||||
if (!$next['type']) $next['type'] = 'stable';
|
||||
if (!$next['date']) $next['date'] = date('Y-m-d');
|
||||
if (!$next['codename']) $next['codename'] = $current['codename'];
|
||||
$next['codename'] = ucwords(strtolower($next['codename']));
|
||||
|
||||
if (!in_array($next['type'], ['stable', 'hotfix', 'rc'])) {
|
||||
throw new \splitbrain\phpcli\Exception('Invalid release type, use release or rc');
|
||||
}
|
||||
|
||||
if ($next['type'] === 'hotfix') {
|
||||
$next['update'] = floatval($current['update']) + 0.1;
|
||||
$next['codename'] = $current['codename'];
|
||||
$next['date'] = $current['date'];
|
||||
$next['hotfix'] = $this->increaseHotfix($current['hotfix']);
|
||||
} else {
|
||||
$next['update'] = intval($current['update']) + 1;
|
||||
}
|
||||
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $next['date'])) {
|
||||
throw new \splitbrain\phpcli\Exception('Invalid date format, use YYYY-MM-DD');
|
||||
}
|
||||
|
||||
if ($current['date'] > $next['date']) {
|
||||
throw new \splitbrain\phpcli\Exception('Date must be equal or later than the last release');
|
||||
}
|
||||
|
||||
if ($current['type'] === 'rc' && $next['type'] === 'hotfix') {
|
||||
throw new \splitbrain\phpcli\Exception(
|
||||
'Cannot create hotfixes for release candidates, create a new RC instead'
|
||||
);
|
||||
}
|
||||
|
||||
if ($current['type'] === 'stable' && $next['type'] !== 'hotfix' && $current['codename'] === $next['codename']) {
|
||||
throw new \splitbrain\phpcli\Exception('Codename must be different from the last release');
|
||||
}
|
||||
|
||||
$next['version'] = $next['date'] . ($next['type'] === 'rc' ? 'rc' : $next['hotfix']);
|
||||
$next['raw'] = ($next['type'] === 'rc' ? 'rc' : '') .
|
||||
$next['date'] .
|
||||
$next['hotfix'] .
|
||||
' "' . $next['codename'] . '"';
|
||||
|
||||
// output to be piped into GITHUB_ENV
|
||||
foreach ($current as $k => $v) {
|
||||
echo "current_$k=$v\n";
|
||||
}
|
||||
foreach ($next as $k => $v) {
|
||||
echo "next_$k=$v\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current version info from local VERSION file
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getLocalVersion()
|
||||
{
|
||||
$versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents('VERSION')));
|
||||
$doku = file_get_contents('doku.php');
|
||||
if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) {
|
||||
throw new \Exception('Could not find $updateVersion in doku.php');
|
||||
}
|
||||
$versioninfo['update'] = floatval($m[1]);
|
||||
return $versioninfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current version info from stable branch
|
||||
*
|
||||
* @return string[]
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getUpstreamVersion()
|
||||
{
|
||||
// basic version info
|
||||
$versioninfo = \dokuwiki\Info::parseVersionString(trim(file_get_contents($this->BASERAW . 'VERSION')));
|
||||
|
||||
// update version grepped from the doku.php file
|
||||
$doku = file_get_contents($this->BASERAW . 'doku.php');
|
||||
if (!preg_match('/\$updateVersion = "(\d+(\.\d+)?)";/', $doku, $m)) {
|
||||
throw new \Exception('Could not find $updateVersion in doku.php');
|
||||
}
|
||||
$versioninfo['update'] = floatval($m[1]);
|
||||
|
||||
return $versioninfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the hotfix letter
|
||||
*
|
||||
* (max 26 hotfixes)
|
||||
*
|
||||
* @param string $hotfix
|
||||
* @return string
|
||||
*/
|
||||
protected function increaseHotfix($hotfix)
|
||||
{
|
||||
if (empty($hotfix)) return 'a';
|
||||
return substr($hotfix, 0, -1) . chr(ord($hotfix) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
(new Release())->run();
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Command line tool to check proper version strings
|
||||
*
|
||||
* Expects a tag as first argument. Used in release action to ensure proper formats
|
||||
* in VERSION file and git tag.
|
||||
*/
|
||||
|
||||
if (!isset($argv[1])) {
|
||||
echo "::error::No git tag given, this action should not have run\n";
|
||||
exit(1);
|
||||
}
|
||||
$TAG = $argv[1];
|
||||
$TAG = str_replace('refs/tags/', '', $TAG);
|
||||
|
||||
if (!file_exists(__DIR__ . '/../VERSION')) {
|
||||
echo "::error::No VERSION file found\n";
|
||||
exit(1);
|
||||
}
|
||||
$FILE = trim(file_get_contents(__DIR__ . '/../VERSION'));
|
||||
$FILE = explode(' ', $FILE)[0];
|
||||
|
||||
|
||||
if(!preg_match('/^release_(stable|candidate)_((\d{4})-(\d{2})-(\d{2})([a-z])?)$/', $TAG, $m)) {
|
||||
echo "::error::Git tag does not match expected format: $TAG\n";
|
||||
exit(1);
|
||||
} else {
|
||||
$TAGTYPE = $m[1];
|
||||
$TAGVERSION = $m[2];
|
||||
}
|
||||
|
||||
if(!preg_match('/^(rc)?((\d{4})-(\d{2})-(\d{2})([a-z])?)$/', $FILE, $m)) {
|
||||
echo "::error::VERSION file does not match expected format: $FILE\n";
|
||||
exit(1);
|
||||
} else {
|
||||
$FILETYPE = $m[1] == 'rc' ? 'candidate' : 'stable';
|
||||
$FILEVERSION = $m[2];
|
||||
$TGZVERSION = $m[0];
|
||||
}
|
||||
|
||||
if($TAGTYPE !== $FILETYPE) {
|
||||
echo "::error::Type of release mismatches between git tag and VERSION file: $TAGTYPE <-> $FILETYPE\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($TAGVERSION !== $FILEVERSION) {
|
||||
echo "::error::Version date mismatches between git tag and VERSION file: $TAGVERSION <-> $FILEVERSION\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// still here? all good, export Version
|
||||
echo "::set-output name=VERSION::$TGZVERSION\n";
|
|
@ -0,0 +1,39 @@
|
|||
# This workflow updates the list of deleted files based on the recent changes and creates a pull request.
|
||||
# It compares the current master with the stable branch and adds all deleted files to the data/deleted.files file
|
||||
# unless they are already listed there or are excluded from the release archives (export-ignore in .gitattributes).
|
||||
|
||||
name: "Update deleted files"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Update deleted files
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Update deleted files
|
||||
run: |
|
||||
for F in $(git diff origin/stable..HEAD --summary | awk '/^ delete/ && $4 !~ /^(VERSION)/ {print $4}'); do
|
||||
if grep -q "^$F export-ignore" .gitattributes; then
|
||||
continue
|
||||
fi
|
||||
if grep -q "^$F" data/deleted.files; then
|
||||
continue
|
||||
fi
|
||||
echo "$F" >> data/deleted.files
|
||||
done
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "Update deleted files"
|
||||
title: "Update deleted files"
|
||||
body: "This updates the list of deleted files based on the recent changes."
|
||||
delete-branch: true
|
|
@ -0,0 +1,106 @@
|
|||
# This workflow creates a new tag, builds the release archives and uploads them to GitHub and our server
|
||||
# It is triggered by pushing to the stable branch, either manually or by merging a PR created by the
|
||||
# release-preparation workflow
|
||||
|
||||
name: "Release: Tag, Build & Deploy"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- stable
|
||||
|
||||
jobs:
|
||||
|
||||
tag:
|
||||
name: Tag Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
php .github/release.php current >> $GITHUB_ENV
|
||||
|
||||
- name: Check if a tag already exists
|
||||
run: |
|
||||
if git rev-parse "release-${{ env.current_version }}" >/dev/null 2>&1; then
|
||||
echo "::error::Tag already exists, be sure to update the VERSION file for a hotfix"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create tag
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
# a privileged token is needed here to create the (protected) tag
|
||||
github-token: ${{ secrets.RELEASE_TOKEN }}
|
||||
script: |
|
||||
const {current_version} = process.env;
|
||||
github.rest.git.createRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: `refs/tags/release-${current_version}`,
|
||||
sha: context.sha
|
||||
});
|
||||
|
||||
build:
|
||||
name: Build Release
|
||||
needs: tag
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
php .github/release.php current >> $GITHUB_ENV
|
||||
|
||||
- name: Build Archives
|
||||
run: |
|
||||
for F in $(awk '/export-ignore/{print $1}' .gitattributes); do
|
||||
rm -rf $F
|
||||
done
|
||||
mkdir -p data/pages/playground
|
||||
echo "====== PlayGround ======" > data/pages/playground/playground.txt
|
||||
cd ..
|
||||
mv ${{ github.event.repository.name }} "dokuwiki-${{ env.current_file }}"
|
||||
tar -czvf "dokuwiki-${{ env.current_file }}.tgz" dokuwiki-${{ env.current_file }}
|
||||
zip -r "dokuwiki-${{ env.current_file }}.zip" dokuwiki-${{ env.current_file }}
|
||||
rm -rf "dokuwiki-${{ env.current_file }}"
|
||||
mkdir ${{ github.event.repository.name }}
|
||||
mv "dokuwiki-${{ env.current_version }}.tgz" ${{ github.event.repository.name }}/
|
||||
mv "dokuwiki-${{ env.current_version }}.zip" ${{ github.event.repository.name }}/
|
||||
|
||||
- name: Release to Github
|
||||
id: release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: DokuWiki ${{ env.current_raw }} [${{ env.current_update }}]
|
||||
tag_name: release-${{ env.current_version }}
|
||||
files: |
|
||||
dokuwiki-${{ env.current_file }}.tgz
|
||||
dokuwiki-${{ env.current_file }}.zip
|
||||
outputs:
|
||||
version: ${{ env.current_version }}
|
||||
file: ${{ env.current_file }}
|
||||
url: ${{ steps.release.outputs.url }}
|
||||
|
||||
deploy:
|
||||
name: Deploy Release
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download
|
||||
run: |
|
||||
wget ${{ needs.build.outputs.url }}/dokuwiki-${{ needs.build.outputs.file }}.tgz
|
||||
|
||||
- name: Setup SSH Key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
with:
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
# generate with ssh-keyscan -H <server>
|
||||
known_hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
|
||||
- name: Deploy to Server
|
||||
run: |
|
||||
scp "dokuwiki-${{ needs.build.outputs.file }}.tgz" ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:htdocs/src/dokuwiki/
|
||||
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "cd htdocs/src/dokuwiki/ && tar -xzvf dokuwiki-${{ needs.build.outputs.file }}.tgz"
|
|
@ -0,0 +1,102 @@
|
|||
# This workflow is triggered manually and prepares a new release by creating a pull request
|
||||
# All needed info is provided by the user in the workflow_dispatch dialog
|
||||
#
|
||||
# When the pull request is merged, the release-build workflow will be triggered automatically
|
||||
|
||||
name: "Release: Preparation 🚀"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
type:
|
||||
description: 'What type of release is this?'
|
||||
required: true
|
||||
default: 'stable'
|
||||
type: choice
|
||||
options:
|
||||
- stable
|
||||
- hotfix
|
||||
- rc
|
||||
codename:
|
||||
description: 'The codename for this release, empty for same as last'
|
||||
required: false
|
||||
version:
|
||||
description: 'The version date YYYY-MM-DD, empty for today'
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
create:
|
||||
name: Prepare Pull Request
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fail if branch is not master
|
||||
if: github.ref != 'refs/heads/master'
|
||||
run: |
|
||||
echo "::error::This workflow should only be triggered on master"
|
||||
exit 1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set git identity
|
||||
run: |
|
||||
git config --global user.name "${{ github.actor }}"
|
||||
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
|
||||
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
php .github/release.php new \
|
||||
--date "${{ inputs.version }}" \
|
||||
--name "${{ inputs.codename }}" \
|
||||
--type "${{ inputs.type }}" \
|
||||
>> $GITHUB_ENV
|
||||
|
||||
- name: Check if a tag of the new release already exists
|
||||
run: |
|
||||
if git rev-parse "release-${{ env.next_version }}" >/dev/null 2>&1; then
|
||||
echo "::error::Tag already exists, you may need to build a hotfix instead"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create merge commit with version info
|
||||
run: |
|
||||
git merge -s ours origin/stable
|
||||
echo '${{ env.next_raw }}' > VERSION
|
||||
git add VERSION
|
||||
git commit --amend -m 'Release preparations for ${{ env.next_raw }}'
|
||||
git log -1
|
||||
git log origin/stable..master --oneline
|
||||
git checkout -B auto-${{ env.next_version }}
|
||||
git push --set-upstream origin auto-${{ env.next_version }}
|
||||
|
||||
- name: Create pull request
|
||||
uses: repo-sync/pull-request@v2
|
||||
with:
|
||||
source_branch: auto-${{ env.next_version }}
|
||||
destination_branch: stable
|
||||
pr_title: Release Preparations for ${{ env.next_raw }}
|
||||
pr_body: |
|
||||
With accepting this PR, a the stable branch will be updated and the whole release and
|
||||
deployment process will be triggered.
|
||||
|
||||
If you're not happy with the contents of this PR, please close it, fix stuff and trigger
|
||||
the workflow again.
|
||||
|
||||
* ${{ env.current_raw }} -> ${{ env.next_raw }}
|
||||
* Update Version ${{ env.current_update }} -> ${{ env.next_update }}
|
||||
|
||||
Before merging this PR, make sure that:
|
||||
|
||||
- [ ] Ensure all tests pass
|
||||
- [ ] If this is a new stable release, make sure you merged `stable` into `old-stable` first
|
||||
- [ ] Check that a meaningful [changelog](https://www.dokuwiki.org/changes) exists
|
||||
|
||||
After merging, the release workflow will be triggered automatically.
|
||||
|
||||
After this is done, you need to do the following things manually:
|
||||
|
||||
- [ ] Update the [version symlinks](https://download.dokuwiki.org/admin/)
|
||||
- [ ] Update the update message system
|
||||
- [ ] Announce the release on the mailing list, forum, IRC, social media, etc.
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
name: Build and Publish
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.4
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: php .github/version.php "${GITHUB_REF}"
|
||||
|
||||
- name: Build TGZ
|
||||
run: |
|
||||
rm -rf .gitignore
|
||||
rm -rf .git
|
||||
rm -rf .github
|
||||
rm -rf .gitattributes
|
||||
rm -rf _test
|
||||
rm -f .editorconfig
|
||||
mkdir -p data/pages/playground
|
||||
echo "====== PlayGround ======" > data/pages/playground/playground.txt
|
||||
cd ..
|
||||
mv dokuwiki "dokuwiki-${{ steps.get_version.outputs.VERSION }}"
|
||||
tar -czvf "dokuwiki-${{ steps.get_version.outputs.VERSION }}.tgz" dokuwiki-${{ steps.get_version.outputs.VERSION }}
|
||||
rm -rf "dokuwiki-${{ steps.get_version.outputs.VERSION }}"
|
||||
mkdir dokuwiki
|
||||
mv "dokuwiki-${{ steps.get_version.outputs.VERSION }}.tgz" dokuwiki/
|
||||
|
||||
- name: Setup SSH Key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
with:
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
# generate with ssh-keyscan -H <server>
|
||||
known_hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
|
||||
|
||||
- name: Deploy to Server
|
||||
run: |
|
||||
scp "dokuwiki-${{ steps.get_version.outputs.VERSION }}.tgz" ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:htdocs/src/dokuwiki/
|
||||
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "cd htdocs/src/dokuwiki/ && tar -xzvf dokuwiki-${{ steps.get_version.outputs.VERSION }}.tgz"
|
Loading…
Reference in New Issue