Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Github workflow to allow for automatic preview releases #22367

Merged
merged 22 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
437286f
Add PHP method to determine next preview version number
michalkleiner Jul 3, 2024
afa4bd0
Allow to use preview release branch in tests via an input param
michalkleiner Jul 3, 2024
b6469be
Allow to fail fast in tests via an input param
michalkleiner Jul 3, 2024
114a095
Add preview release workflow
michalkleiner Jul 3, 2024
81059db
Use assertEmpty in unit tests to check if there's no preview version
michalkleiner Jul 3, 2024
2f0eb9a
Apply suggestions from code review
michalkleiner Jul 4, 2024
ac533bf
Make tests job conditional on the prepare job outputs
michalkleiner Jul 4, 2024
12d955f
Fix next preview version generation to correctly bump patch or b/rc i…
michalkleiner Jul 5, 2024
f680343
Adjust release workflow to be able to be reused
michalkleiner Jul 5, 2024
3177803
Reuse release action to create preview releases
michalkleiner Jul 5, 2024
275c569
Tidy up for consistency
michalkleiner Jul 5, 2024
1197faf
Fix name reference
michalkleiner Jul 5, 2024
85fdef2
Add a check whether previous non-stable version has been released
michalkleiner Jul 5, 2024
6f5e278
Skip release checks for -alpha as that won't ever be released
michalkleiner Jul 5, 2024
6d18826
Fix output variable name
michalkleiner Jul 5, 2024
383815c
Tweak conditional logic
michalkleiner Jul 9, 2024
4a79b30
Fix regex by adding the missing delimiter
michalkleiner Jul 12, 2024
311e303
Use regex assert method
michalkleiner Jul 12, 2024
aa63485
Fix typo in test value
michalkleiner Jul 12, 2024
bea5ed1
Adjust release preview to require password and verify user
caddoo Aug 8, 2024
9120e23
Set ENV variable and remove redundent check
caddoo Aug 9, 2024
a27a9b7
Merge branch '5.x-dev' into preview-automation
caddoo Aug 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/workflows/matomo-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ on:
- '**.x-dev'
- 'next_release'
workflow_dispatch:
workflow_call:
inputs:
is_preview:
type: boolean
required: false
default: false

permissions:
actions: read
Expand All @@ -34,7 +40,7 @@ jobs:
PHP:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
fail-fast: ${{ inputs.is_preview == true }}
matrix:
type: [ 'UnitTests', 'SystemTestsPlugins', 'SystemTestsCore', 'IntegrationTestsCore', 'IntegrationTestsPlugins' ]
php: [ '7.2', '8.2', '8.3' ]
Expand All @@ -60,6 +66,7 @@ jobs:
persist-credentials: false
submodules: true
path: matomo
ref: ${{ inputs.is_preview == true && '5.x-preview' || github.ref }}
mneudert marked this conversation as resolved.
Show resolved Hide resolved
- name: running tests
uses: matomo-org/github-action-tests@main
with:
Expand All @@ -81,6 +88,7 @@ jobs:
persist-credentials: false
submodules: true
path: matomo
ref: ${{ inputs.is_preview == true && '5.x-preview' || github.ref }}
- name: running tests
uses: matomo-org/github-action-tests@main
with:
Expand All @@ -97,6 +105,7 @@ jobs:
persist-credentials: false
submodules: true
path: matomo
ref: ${{ inputs.is_preview == true && '5.x-preview' || github.ref }}
- name: running tests
uses: matomo-org/github-action-tests@main
with:
Expand All @@ -106,7 +115,7 @@ jobs:
UI:
runs-on: ubuntu-20.04
strategy:
fail-fast: false
fail-fast: ${{ inputs.is_preview == true }}
matrix:
parts: [ 0,1,2,3 ]
steps:
Expand All @@ -116,6 +125,7 @@ jobs:
persist-credentials: false
submodules: true
path: matomo
ref: ${{ inputs.is_preview == true && '5.x-preview' || github.ref }}
- name: running tests
uses: matomo-org/github-action-tests@main
with:
Expand Down
169 changes: 169 additions & 0 deletions .github/workflows/release-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Matomo release action for automated PREVIEW releases
#
# Required GitHub secrets:
#
# GPG_CERTIFICATE | ASCII armored or Base64 encoded GPG certificate that is used to create the signatures for the archives
# GPG_CERTIFICATE_PASS | Passphrase of the GPG key

name: Build preview release

permissions:
actions: read # required for the tests job
checks: none
contents: write # required to create tag and release
deployments: none
issues: read # required for the tests job
packages: none
pull-requests: read # required for the tests jobs
repository-projects: none
security-events: none
statuses: none

on:
# TODO: remove manual dispatch after testing and enable cron
workflow_dispatch:
branches:
- 5.x-dev
inputs:
password:
description: 'Release password'
required: true
#schedule:
# - cron: '0 1 * * *' # 1am daily
env:
RELEASE_PASSWORD: ${{ secrets.RELEASE_PASSWORD }}
jobs:
prepare_preview_version:
runs-on: ubuntu-latest
outputs:
do_release: ${{ steps.changes.outputs.do_release }}
has_new_version: ${{ steps.version.outputs.has_new_version }}
steps:
- name: "Check release password"
if: ${{ github.event.inputs.password != env.RELEASE_PASSWORD }}
uses: actions/github-script@v6
with:
script: |
core.setFailed('Release password didn\'t match.')
- name: "Check if user is allowed"
if: ${{ github.actor != 'mattab' && github.actor != 'tsteur' && github.actor != 'sgiehl' && github.actor != 'mneudert' && github.actor != 'michalkleiner' && github.actor != 'caddoo'}}
uses: actions/github-script@v6
with:
script: |
core.setFailed('User is not allowed to release.')
- uses: actions/checkout@v4
with:
lfs: false
fetch-tags: true
fetch-depth: 0

- name: Prepare git config
run: |
cat <<- EOF > $HOME/.netrc
machine github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
machine api.github.com
login $GITHUB_ACTOR
password $GITHUB_TOKEN
EOF
chmod 600 $HOME/.netrc
git config --global user.email "[email protected]"
git config --global user.name "$GITHUB_ACTOR"
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check if there are any changes to create a preview release for
id: changes
mneudert marked this conversation as resolved.
Show resolved Hide resolved
run: |
LATEST_PREVIEW=$(git tag --sort=-creatordate | grep -E '\.[0-9]{14}$' | head -n 1)

DIFF=""
if [ -n "$LATEST_PREVIEW" ]; then
# using || true to always exit either with a diff or a success exit code to not fail the whole workflow
DIFF=$(git diff $LATEST_PREVIEW..5.x-dev --unified=0 | grep -vE "^\+\+\+|---" | grep "^[+-]" | grep -v "public const VERSION = '.*';" || true)
michalkleiner marked this conversation as resolved.
Show resolved Hide resolved
fi

if [ -z "$DIFF" ]; then
echo "No changes in 5.x-dev since last preview version was created."
DO_RELEASE=0
else
DO_RELEASE=1
fi

echo "do_release=$DO_RELEASE" >> $GITHUB_OUTPUT

- name: Determine new preview version number
id: version
if: steps.changes.outputs.do_release == '1'
run: |
OLD_VERSION=$(php -r "include_once 'core/Version.php'; echo \Piwik\Version::VERSION;")
NEW_VERSION=$(php -r "include_once 'core/Version.php'; \$v = new \Piwik\Version(); echo \$v->nextPreviewVersion(\Piwik\Version::VERSION);")

if [ "$NEW_VERSION" == "" ]; then
HAS_NEW_VERSION=0
else
HAS_NEW_VERSION=1
fi

echo "OLD_VERSION=$OLD_VERSION" >> $GITHUB_ENV
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV

echo "has_new_version=$HAS_NEW_VERSION" >> $GITHUB_OUTPUT
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT

- name: Check if the previous version has been released
if: steps.changes.outputs.do_release == '1' && steps.version.outputs.has_new_version == '1'
run: |
TAG_EXISTS=$( git tag --list "$OLD_VERSION" )

# x.y.z-alpha would not be released, all other versions should have an existing tag (a release)
if [[ ! $OLD_VERSION =~ -alpha$ ]] && [[ -z "$TAG_EXISTS" ]]; then
echo "$OLD_VERSION (as indicated in core/Version.php) has not been released yet."
exit 1
fi

- name: Update 5.x-preview branch to latest 5.x-dev
if: steps.changes.outputs.do_release == '1' && steps.version.outputs.has_new_version == '1'
run: |
git checkout -B 5.x-preview

- name: Update version file with new version
if: steps.changes.outputs.do_release == '1' && steps.version.outputs.has_new_version == '1'
run: |
sed -i "s/VERSION = '${OLD_VERSION}';/VERSION = '${NEW_VERSION}';/g" core/Version.php

- name: Commit version file changes
if: steps.changes.outputs.do_release == '1' && steps.version.outputs.has_new_version == '1'
run: |
git add core/Version.php
git commit -m "Update version to ${NEW_VERSION}"

- name: Push changes to 5.x-preview
if: steps.changes.outputs.do_release == '1' && steps.version.outputs.has_new_version == '1'
run: |
git push -f origin 5.x-preview

run_matomo_tests:
needs: [prepare_preview_version]
uses: ./.github/workflows/matomo-tests.yml
if: |
always() &&
needs.prepare_preview_version.result == 'success' &&
needs.prepare_preview_version.outputs.do_release == '1' &&
needs.prepare_preview_version.outputs.has_new_version == '1'
with:
is_preview: true

release_preview_version:
needs: [run_matomo_tests]
uses: ./.github/workflows/release.yml
if: |
always() &&
needs.prepare_preview_version.result == 'success' &&
needs.run_matomo_tests.result == 'success' &&
needs.prepare_preview_version.outputs.do_release == '1' &&
needs.prepare_preview_version.outputs.has_new_version == '1'
with:
is_preview: true
22 changes: 17 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ on:
password:
description: 'Release password'
required: true
workflow_call:
inputs:
is_preview:
type: boolean
required: false
default: false

env:
RELEASE_PASSWORD: ${{ secrets.RELEASE_PASSWORD }}
Expand All @@ -39,13 +45,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "Check release password"
if: ${{ github.event.inputs.password != env.RELEASE_PASSWORD }}
if: ${{ inputs.is_preview != true && github.event.inputs.password != env.RELEASE_PASSWORD }}
uses: actions/github-script@v6
with:
script: |
core.setFailed('Release password didn\'t match.')
- name: "Check if user is allowed"
if: ${{ github.actor != 'mattab' && github.actor != 'tsteur' && github.actor != 'sgiehl' && github.actor != 'mneudert' && github.actor != 'michalkleiner' && github.actor != 'caddoo'}}
if: ${{ inputs.is_preview != true && github.actor != 'mattab' && github.actor != 'tsteur' && github.actor != 'sgiehl' && github.actor != 'mneudert' && github.actor != 'michalkleiner' && github.actor != 'caddoo'}}
uses: actions/github-script@v6
with:
script: |
Expand Down Expand Up @@ -97,15 +103,21 @@ jobs:
exit 1
fi

if ! [[ ${GITHUB_REF#refs/heads/} =~ ^[4-9]\.x-dev$ || ${GITHUB_REF#refs/heads/} == "next_release" ]]
if ! [[ ${GITHUB_REF#refs/heads/} =~ ^[4-9]\.x-(dev|preview)$ || ${GITHUB_REF#refs/heads/} == "next_release" ]]
then
echo "A tag can only be created from branches '5.x-dev' and 'next_release'. Please create the tag manually if a release needs to be built from another branch."
echo "A tag can only be created from branches '5.x-dev', '5.x-preview' or 'next_release'. Please create the tag manually if a release needs to be built from another branch."
exit 1
fi

if [[ ${GITHUB_REF#refs/heads/} =~ ^[4-9]\.x-dev$ && $version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$ ]]
then
echo "Only beta/preview release tags can be created from ${GITHUB_REF#refs/heads/} branch."
echo "Only beta release tags can be created from ${GITHUB_REF#refs/heads/} branch."
exit 1
fi

if [[ ${GITHUB_REF#refs/heads/} =~ ^[4-9]\.x-preview$ && $version =~ [0-9]{14}$ ]]
then
echo "Only preview release tags can be created from ${GITHUB_REF#refs/heads/} branch."
exit 1
fi

Expand Down
49 changes: 47 additions & 2 deletions core/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ public function isVersionNumber($version): bool

private function isNonStableVersion($version): bool
{
return (bool) preg_match('/^\d+\.\d+\.\d+((-.{1,4}\d+(\.\d{14})?)|(-alpha\.\d{14}))$/i', $version);
return (bool) preg_match('/^\d+\.\d+\.\d+(-((rc|b|beta)\d+|alpha)(\.\d{14})?)$/i', $version);
}

public function isPreviewVersion($version): bool
{
if (\preg_match('/^\d+\.\d+\.\d+((-(rc|b|beta)\d+(\.\d{14})?)|(-alpha\.\d{14}))?$/i', $version)) {
if ($this->isNonStableVersion($version)) {
if (\preg_match('/\.(\d{14})$/', $version, $matches)) {
$dt = DateTime::createFromFormat('YmdHis', $matches[1]);

Expand All @@ -56,4 +56,49 @@ public function isPreviewVersion($version): bool

return false;
}

public function nextPreviewVersion($version): string
{
if (!$this->isVersionNumber($version)) {
return '';
}

$dt = date('YmdHis');

if ($this->isPreviewVersion($version)) {
// already a preview, update dt and check it's newer
$newVersion = substr($version, 0, -14) . $dt;
if (version_compare($version, $newVersion, '<')) {
return $newVersion;
}
return '';
} elseif ($this->isStableVersion($version)) {
// no suffix yet, we need to bump the patch first
$newVersion = preg_replace_callback(
'/^(\d+\.\d+\.)(\d+)$/',
function ($matches) {
$matches[2] = $matches[2] + 1;
return $matches[1] . $matches[2];
},
$version
);

return sprintf('%s-alpha.%s', $newVersion, $dt);
} elseif ('alpha' === substr($version, -5)) {
// -alpha
return $version . '.' . $dt;
} else {
// -b1, -rc1
$newVersion = preg_replace_callback(
'/^(\d+\.\d+\.\d+-(?:rc|b|beta))(\d+)$/i',
function ($matches) {
$matches[2] = $matches[2] + 1;
return $matches[1] . $matches[2];
},
$version
);

return $newVersion . '.' . $dt;
}
}
}
Loading
Loading