Skip to content

Commit

Permalink
Merge branch 'master' into release/T24.chapa
Browse files Browse the repository at this point in the history
  • Loading branch information
Camwyn committed Jul 22, 2024
2 parents 8768a33 + 9e6fb68 commit bbabc62
Show file tree
Hide file tree
Showing 12 changed files with 2,389 additions and 520 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ indent_style = tab
insert_final_newline = false
trim_trailing_whitespace = true

[**.{jshintrc,json,scss-lint,yml}]
[**.{jshintrc,json,neon,scss-lint,yml}]
indent_style = space
indent_size = 2
43 changes: 43 additions & 0 deletions .github/workflows/changelogger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Check changelog

on:
pull_request:
branches:
- master
- 'release/**'
paths-ignore:
- '.github/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check-changelog:
name: Check changelog
runs-on: ubuntu-latest
steps:
# clone the repository
- uses: actions/checkout@v4
with:
fetch-depth: 1000
submodules: recursive
# enable dependencies caching
- name: Add composer to cache
uses: actions/cache@v4
with:
path: ~/.cache/composer/
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
# setup PHP
- name: Configure PHP environment
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
tools: composer
coverage: none
# Install composer packages.
- run: composer self-update && composer install --no-progress
# Fetch the target branch before running the check.
- name: Fetch the target origin branch
run: git fetch origin $GITHUB_BASE_REF
# Check if any changelog file is added when comparing the current branch vs the target branch.
- name: Check changelog
run: bash bin/check-changelog.sh origin/$GITHUB_BASE_REF HEAD
2 changes: 1 addition & 1 deletion .github/workflows/link-project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ jobs:
template-project-url: https://github.com/orgs/the-events-calendar/projects/29
project-owner: 'tec-bot'
base-branch-pattern: 'release/*'
name-prefix-remove: 'release/'
name-prefix-remove: 'release/'
27 changes: 27 additions & 0 deletions bin/check-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash

BASE=${1-origin/master}
HEAD=${2-HEAD}

# Get only added files from git diff.
CHANGELOG_FILES=$(git diff --name-only --diff-filter=A "$BASE" "$HEAD" | grep '^changelog\/')

if [[ -n "$CHANGELOG_FILES" ]]; then
echo "Found changelog file(s):"
echo "$CHANGELOG_FILES"
else
echo "::error::No changelog found."
echo "Add at least one changelog file for your PR by running: npm run changelog"
echo "Choose *patch* to leave it empty if the change is not significant. You can add multiple changelog files in one PR by running this command a few times."
echo "Remove changelog in readme.txt and changelog.md if you have already added them in your PR."
exit 1
fi

echo "Validating changelog files..."
CHECK=$(./vendor/bin/changelogger validate --gh-action)
if [[ -z "$CHECK" ]]; then
echo "All changelog files are valid."
else
echo $CHECK
exit 1
fi
224 changes: 224 additions & 0 deletions bin/class-tec-changelog-formatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php
/**
* Jetpack Changelogger Formatter for The Events Calendar
*
* @package The Events Calendar
*/

// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
use Automattic\Jetpack\Changelog\Changelog;
use Automattic\Jetpack\Changelog\Parser;
use Automattic\Jetpack\Changelogger\FormatterPlugin;
use Automattic\Jetpack\Changelogger\PluginTrait;

/**
* Jetpack Changelogger Formatter for The Events Calendar
*
* Class TEC_Changelog_Formatter
*/
class TEC_Changelog_Formatter extends Parser implements FormatterPlugin {
use PluginTrait;

/**
* Bullet for changes.
*
* @var string
*/
private $bullet = '*';

/**
* Output date format.
*
* @var string
*/
private $date_format = 'Y-m-d';

/**
* Title for the changelog.
*
* @var string
*/
private $title = '# Changelog';

/**
* Separator used in headings and change entries.
*
* @var string
*/
private $separator = '-';

/**
* Modified version of parse() from KeepAChangelogParser.
*
* @throws Exception If a heading has invalid timestamp.
* @throws InvalidArgumentException If the changelog data cannot be parsed.
*
* @param string $changelog Changelog contents.
* @return Changelog
*/
public function parse( $changelog ) {
$ret = new Changelog();

// Fix newlines and expand tabs.
$changelog = strtr( $changelog, [ "\r\n" => "\n" ] );
$changelog = strtr( $changelog, [ "\r" => "\n" ] );
while ( strpos( $changelog, "\t" ) !== false ) {
$changelog = preg_replace_callback(
'/^([^\t\n]*)\t/m',
function ( $m ) {
return $m[1] . str_repeat( ' ', 4 - ( mb_strlen( $m[1] ) % 4 ) );
},
$changelog
);
}

// Remove title. Check if the first line containing the defined title, and remove it.
$changelog_parts = explode( "\n", $changelog, 2 );
$first_line = $changelog_parts[0] ?? '';
$remaining = $changelog_parts[1] ?? '';

if ( false !== strpos( $first_line, $this->title ) ) {
$changelog = $remaining;
}

// Entries make up the rest of the document.
$entries = [];
preg_match_all( '/^###\s+\[([^\n=]+)\]\s+([^\n=]+)([\s\S]*?)(?=^###\s+|\z)/m', $changelog, $version_sections );

foreach ( $version_sections[0] as $section ) {
$heading_pattern = '/^### +\[([^\] ]+)\] (.+)/';
// Parse the heading and create a ChangelogEntry for it.
preg_match( $heading_pattern, $section, $heading );
if ( ! count( $heading ) ) {
throw new InvalidArgumentException( "Invalid heading: $heading" );
}

$version = $heading[1];
$timestamp = $heading[2];
if ( $timestamp === $this->get_unreleased_date() ) {
$timestamp = null;
$entry_timestamp = new DateTime( 'now', new DateTimeZone( 'UTC' ) );
} else {
try {
$timestamp = new DateTime( $timestamp, new DateTimeZone( 'UTC' ) );
} catch ( \Exception $ex ) {
throw new InvalidArgumentException( "Heading has an invalid timestamp: $heading", 0, $ex );
}
if ( strtotime( $heading[2], 0 ) !== strtotime( $heading[2], 1000000000 ) ) {
throw new InvalidArgumentException( "Heading has a relative timestamp: $heading" );
}
$entry_timestamp = $timestamp;
}

$entry = $this->newChangelogEntry(
$version,
[
'timestamp' => $timestamp,
]
);

$entries[] = $entry;
$content = trim( preg_replace( $heading_pattern, '', $section ) );

if ( '' === $content ) {
// Huh, no changes.
continue;
}

// Now parse all the subheadings and changes.
while ( '' !== $content ) {
$changes = [];
$rows = explode( "\n", $content );
foreach ( $rows as $row ) {
$is_entry = substr( $row, 0, 1 ) === $this->bullet;

// It's a multi line entry - add them to previous as content unformatted.
if ( ! $is_entry ) {
$changes[ count( $changes ) - 1 ]['content'] .= "\n" . $row;
continue;
}

$row = trim( $row );
$row = preg_replace( '/\\' . $this->bullet . '/', '', $row, 1 );

$row_segments = explode( $this->separator, $row, 2 );

if ( count( $row_segments ) !== 2 ) {
// Current row (change entry) does not have correct format.
// It usually happens before migrating to Jetpack Changelogger.
throw new Exception( 'Change entry does not have the correct format. Please update it manually and run this command again. Change entry: ' . $row );
}

array_push(
$changes,
[
'subheading' => trim( $row_segments[0] ),
'content' => trim( $row_segments[1] ),
]
);
}

foreach ( $changes as $change ) {
$entry->appendChange(
$this->newChangeEntry(
[
'subheading' => $change['subheading'],
'content' => $change['content'],
'timestamp' => $entry_timestamp,
]
)
);
}
$content = '';
}
}

$ret->setEntries( $entries );

return $ret;
}

/**
* Write a Changelog object to a string.
*
* @param Changelog $changelog Changelog object.
* @return string
*/
public function format( Changelog $changelog ) {
$ret = '';

foreach ( $changelog->getEntries() as $entry ) {
$timestamp = $entry->getTimestamp();
$release_date = null === $timestamp ? $this->get_unreleased_date() : $timestamp->format( $this->date_format );

$ret .= '### [' . $entry->getVersion() . '] ' . $release_date . "\n\n";

$prologue = trim( $entry->getPrologue() );
if ( '' !== $prologue ) {
$ret .= "\n$prologue\n\n";
}

foreach ( $entry->getChanges() as $change ) {
$text = trim( $change->getContent() );
if ( '' !== $text ) {
$ret .= $this->bullet . ' ' . $change->getSubheading() . ' ' . $this->separator . ' ' . $text . "\n";
}
}

$ret = trim( $ret ) . "\n\n";
}

$ret = $this->title . "\n\n" . trim( $ret ) . "\n";

return $ret;
}

/**
* Get string used as the date for an unreleased version.
*
* @return string
*/
private function get_unreleased_date(): string {
return gmdate( 'Y' ) . '-xx-xx';
}
}
48 changes: 48 additions & 0 deletions bin/process-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

RELEASE_VERSION=${1-}
CURRENT_VERSION=${2-}
ACTION_TYPE=${3-generate}
RELEASE_DATE=${4-today}

RELEASE_DATE=$( date "+%Y-%m-%d" -d "$RELEASE_DATE" ) # Release date formatted as YYYY-MM-DD

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"

cd $SCRIPT_DIR/../

echo "RELEASE_DATE=$RELEASE_DATE"

if [ "$ACTION_TYPE" == "amend-version" ]; then
sed -i "s/^### \[$CURRENT_VERSION\] .*$/### [$RELEASE_VERSION] $RELEASE_DATE/" changelog.md
else
if [ "$ACTION_TYPE" == "generate" ]; then
CHANGELOG_FLAG=""
echo "Generating the changelog entries."
else
CHANGELOG_FLAG="--amend"
echo "Amending the changelog entries."
fi

# Run changelogger through the project's base dir.
./vendor/bin/changelogger write --use-version="$RELEASE_VERSION" --release-date="$RELEASE_DATE" $CHANGELOG_FLAG --no-interaction --yes
fi

CHANGELOG=$(awk '/^### / { if (p) { exit }; p=1; next } p && NF' changelog.md)

# Escape backslash, new line and ampersand characters. The order is important.
CHANGELOG=${CHANGELOG//\\/\\\\}
CHANGELOG=${CHANGELOG//$'\n'/\\n}
CHANGELOG=${CHANGELOG//&/\\&}

echo "CHANGELOG=$CHANGELOG"

if [ "$ACTION_TYPE" == "amend-version" ]; then
sed -i "s/^= \[$CURRENT_VERSION\] .* =$/= [$RELEASE_VERSION] $RELEASE_DATE =/" readme.txt
else
if [ "$ACTION_TYPE" == "amend" ]; then
perl -i -p0e "s/= \[$RELEASE_VERSION\].*? =(.*?)(\n){2}(?==)//s" readme.txt # Delete the existing changelog for the release version first
fi

sed -ri "s|(== Changelog ==)|\1\n\n= [$RELEASE_VERSION] $RELEASE_DATE =\n\n$CHANGELOG|" readme.txt
fi
Loading

0 comments on commit bbabc62

Please sign in to comment.