Skip to content

Commit 005f461

Browse files
Merge pull request #42 from TrueLayer/feature/2024-10-31-changelog
V2.4.0
2 parents 1ed15d9 + 0d0b16e commit 005f461

39 files changed

+1205
-39
lines changed

.github/workflows/check-version.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Check config.xml version
2+
on:
3+
pull_request:
4+
types: [opened, reopened, synchronize]
5+
branches: [main]
6+
7+
jobs:
8+
check:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v1
12+
with:
13+
ref: ${{ github.event.pull_request.head.sha }}
14+
fetch-depth: 0
15+
16+
- name: Set OLD_VERSION from etc/config.xml if merge would modify it
17+
run: |
18+
echo "OLD_VERSION=$(git log origin/main..HEAD --cherry -p -- etc/config.xml | grep '\-.\s*.<version>' | tail -1 | tr -d '\-[:blank:]\n' | sed -e 's/<version>\(.*\)<\/version>/\1/')" >> $GITHUB_ENV
19+
20+
- name: Set NEW_VERSION from etc/config.xml if merge would modify it
21+
run: |
22+
echo "NEW_VERSION=$(git log origin/main..HEAD --cherry -p -- etc/config.xml | grep '\+.\s*.<version>' | head -1 | tr -d '+[:blank:]\n' | sed -e 's/<version>\(.*\)<\/version>/\1/')" >> $GITHUB_ENV
23+
24+
- name: Test that versions are not empty
25+
run: |
26+
[[ ! -z $OLD_VERSION ]] && [[ ! -z $NEW_VERSION ]]
27+
28+
- name: Test that versions are different
29+
run: |
30+
[[ $OLD_VERSION != $NEW_VERSION ]]
31+
32+
- name: Test that version string mathches pattern
33+
run: |
34+
[[ $NEW_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]$ ]]
35+
36+
- name: Sort versions
37+
run: |
38+
if [[ $OLD_VERSION =~ ^[0-9]+(\.[0-9]+)+\.[0-9]$ ]]; then
39+
echo "GREATER_VERSION=$(echo -e ${OLD_VERSION}\\n${NEW_VERSION} | sort --version-sort | tail -n1)" >> $GITHUB_ENV
40+
else
41+
echo "GREATER_VERSION=$NEW_VERSION" >> $GITHUB_ENV
42+
fi
43+
44+
- name: Make sure new version is greater
45+
run: |
46+
[[ $GREATER_VERSION == $NEW_VERSION ]]
47+
48+
- name: Ensure changelog is not empty for the new version
49+
run: |
50+
CHANGELOG=$(sed -n "/^## \[v$NEW_VERSION\]/,/^## \[v/p" CHANGELOG.md | sed -e "s/^## \[v.*\$//" | sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba')
51+
[[ -n $CHANGELOG ]]
52+
[[ $CHANGELOG == *"### Added"* || $CHANGELOG == *"### Changed"* || $CHANGELOG == *"### Fixed"* ]]

.github/workflows/create-tag.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Create Tag
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags-ignore:
8+
- '**'
9+
10+
jobs:
11+
tag:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v3
15+
with:
16+
fetch-depth: '0'
17+
18+
- name: Generate Git Tag
19+
id: generate_tag
20+
run: |
21+
NEW_TAG=v$(cat etc/config.xml | grep '<version>' | tr -d '\-[:blank:]\n' | sed -e 's/<version>\(.*\)<\/version>/\1/')
22+
echo "NEW_TAG=${NEW_TAG}" >> $GITHUB_ENV
23+
echo "NEW_TAG=${NEW_TAG}" >> $GITHUB_OUTPUT
24+
25+
- name: Test that version string mathches pattern
26+
run: |
27+
[[ $NEW_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]$ ]]
28+
29+
- name: Test for tag collision
30+
run: |
31+
TAG_EXISTS=0
32+
for EXISTING_TAG in `git tag -l`; do
33+
if [[ $EXISTING_TAG == $NEW_TAG || v$EXISTING_TAG == $NEW_TAG ]]; then
34+
TAG_EXISTS=1
35+
break
36+
fi
37+
done
38+
[[ $TAG_EXISTS == 0 ]]
39+
40+
- name: Ensure changelog is not empty for the new tag
41+
run: |
42+
CHANGELOG=$(sed -n "/^## \[$NEW_TAG\]/,/^## \[v/p" CHANGELOG.md | sed -e "s/^## \[v.*\$//" | sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba')
43+
[[ -n $CHANGELOG ]]
44+
[[ $CHANGELOG == *"### Added"* || $CHANGELOG == *"### Changed"* || $CHANGELOG == *"### Fixed"* ]]
45+
- name: Push Git Tag
46+
run: |
47+
git config user.name "GitHub Actions"
48+
git config user.email "[email protected]"
49+
git tag $NEW_TAG
50+
git push origin $NEW_TAG
51+
52+
- name: Create changelog diff
53+
run: |
54+
sed -n "/^## \[$NEW_TAG\]/,/^## \[v/p" CHANGELOG.md | sed -e "s/^## \[v.*\$//" | sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba' > release_notes.md
55+
56+
- name: Create release
57+
id: create_release
58+
uses: actions/create-release@v1
59+
env:
60+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61+
with:
62+
tag_name: ${{ steps.generate_tag.outputs.NEW_TAG }}
63+
release_name: ${{ steps.generate_tag.outputs.NEW_TAG }}
64+
body_path: ./release_notes.md
65+
draft: false
66+
prerelease: false
67+
68+
- name: Delete release_notes file
69+
run: rm release_notes.md

.github/workflows/e2e-tests.yml

Lines changed: 87 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/linting.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ name: Lint PHP files
22
on: [push, pull_request]
33

44
jobs:
5-
php-74:
6-
runs-on: ubuntu-latest
7-
steps:
8-
- uses: prestashop/github-action-php-lint/[email protected]
9-
105
php-81:
116
runs-on: ubuntu-latest
127
steps:

.github/workflows/phpstan.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ jobs:
2828
- name: Set minimum-stability for composer (temp)
2929
run: docker exec magento-project-community-edition composer config minimum-stability dev
3030

31+
- name: Configure composer to mirror repository
32+
run: docker exec magento-project-community-edition composer config repositories.truelayer \{\"type\":\"path\",\"url\":\"/data/extensions/$(basename $(pwd))\",\"options\":\{\"symlink\":false\}\}
33+
3134
- name: Install the extensions in Magento
3235
run: docker exec magento-project-community-edition composer require truelayer/magento2:@dev --no-plugins --with-all-dependencies
3336

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
retries=10
2+
count=0
3+
4+
while [ $count -lt $retries ]; do
5+
mysql -uroot -e "SELECT 1" > /dev/null 2>&1
6+
if [ $? -eq 0 ]; then
7+
echo "MySQL is available."
8+
break
9+
fi
10+
count=$((count+1))
11+
echo "MySQL is not available. Retrying..."
12+
sleep 1
13+
done
14+
15+
if [ $count -eq $retries ]; then
16+
echo "Could not connect to MySQL after $retries retries."
17+
exit 1;
18+
fi
19+
20+
echo "Now connecting to Elasticsearch"
21+
retries=20
22+
count=0
23+
24+
while [ $count -lt $retries ]; do
25+
if curl -s -f -o /dev/null "http://localhost:9200"; then
26+
echo "Elasticsearch is available."
27+
break
28+
else
29+
count=$((count+1))
30+
echo "Attempt $count of $retries: Elasticsearch is not available. Retrying..."
31+
sleep 1
32+
fi
33+
done
34+
35+
if [ $count -eq $retries ]; then
36+
cat /var/log/elasticsearch/elasticsearch.log
37+
echo "Could not connect to Elasticsearch after $retries retries."
38+
fi

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
.DS_Store
55
docker
66
.vscode
7+
.php-cs-fixer.cache
8+
/node_modules
9+
/test-results
10+
/playwright-report
11+
/results.xml
12+
private-key.pem

.php-cs-fixer.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
use PhpCsFixer\Config;
4+
use PhpCsFixer\Finder;
5+
6+
$finder = Finder::create()
7+
->in(__DIR__)
8+
->exclude(['.github', '.vscode', 'docker', 'vendor'])
9+
->ignoreDotFiles(false);
10+
11+
$rules = [
12+
'@PSR1' => true,
13+
'@PSR2' => true,
14+
'@PSR12' => true,
15+
'ordered_imports' => [
16+
'sort_algorithm' => 'alpha',
17+
'imports_order' => [
18+
'class',
19+
'function',
20+
'const'
21+
]
22+
],
23+
'single_line_empty_body' => true,
24+
'array_indentation' => true,
25+
'array_syntax' => ['syntax' => 'short'],
26+
'no_whitespace_in_blank_line' => true,
27+
'whitespace_after_comma_in_array' => [
28+
'ensure_single_space' => true
29+
],
30+
'no_multiline_whitespace_around_double_arrow' => true,
31+
'no_trailing_comma_in_singleline_array' => true,
32+
'normalize_index_brace' => true,
33+
'trim_array_spaces' => true,
34+
'single_class_element_per_statement' => [
35+
'elements' => [
36+
'const',
37+
'property'
38+
]
39+
],
40+
'visibility_required' => [
41+
'elements' => [
42+
'property',
43+
'method',
44+
'const'
45+
]
46+
],
47+
'align_multiline_comment' => true
48+
];
49+
50+
$config = new Config();
51+
$config->setFinder($finder);
52+
$config->setRules($rules);
53+
$config->setIndent(' ');
54+
$config->setLineEnding("\n");
55+
56+
return $config;

Api/Config/System/ConnectionInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ interface ConnectionInterface extends DebugInterface
2525
public const XML_PATH_PRODUCTION_CLIENT_SECRET = 'payment/truelayer/production_client_secret';
2626
public const XML_PATH_PRODUCTION_PRIVATE_KEY = 'payment/truelayer/production_private_key';
2727
public const XML_PATH_PRODUCTION_KEY_ID = 'payment/truelayer/production_key_id';
28+
public const XML_PATH_CACHE_ENCRYPTION_KEY = 'payment/truelayer/cache_encryption_key';
2829

2930
/**
3031
* Get Merchant Account Name

Block/Adminhtml/System/Config/Button/VersionCheck.php

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
namespace TrueLayer\Connect\Block\Adminhtml\System\Config\Button;
99

10-
use TrueLayer\Connect\Api\Config\RepositoryInterface as ConfigRepository;
1110
use Magento\Backend\Block\Template\Context;
1211
use Magento\Config\Block\System\Config\Form\Field;
1312
use Magento\Framework\Data\Form\Element\AbstractElement;
13+
use Magento\Framework\HTTP\Client\Curl;
14+
use TrueLayer\Connect\Api\Config\RepositoryInterface as ConfigRepository;
15+
use TrueLayer\Connect\Api\Log\LogServiceInterface;
1416

1517
/**
1618
* Version check class
@@ -22,10 +24,6 @@ class VersionCheck extends Field
2224
* @var string
2325
*/
2426
protected $_template = 'TrueLayer_Connect::system/config/button/version.phtml';
25-
/**
26-
* @var ConfigRepository
27-
*/
28-
private $configRepository;
2927

3028
/**
3129
* VersionCheck constructor.
@@ -35,10 +33,11 @@ class VersionCheck extends Field
3533
*/
3634
public function __construct(
3735
Context $context,
38-
ConfigRepository $configRepository,
36+
private ConfigRepository $configRepository,
37+
private Curl $curl,
38+
private LogServiceInterface $logger,
3939
array $data = []
4040
) {
41-
$this->configRepository = $configRepository;
4241
parent::__construct($context, $data);
4342
}
4443

@@ -66,6 +65,56 @@ public function _getElementHtml(AbstractElement $element): string
6665
*/
6766
public function getVersion(): string
6867
{
69-
return 'v' . $this->configRepository->getExtensionVersion();
68+
return $this->configRepository->getExtensionVersion();
69+
}
70+
71+
public function getLatestVersion()
72+
{
73+
$curlVersion = $this->getCurlVersion();
74+
$this->curl->addHeader('Accept', 'application/vnd.github+json');
75+
$this->curl->addHeader('User-Agent', 'curl/'.$curlVersion);
76+
$this->curl->setOption(CURLOPT_RETURNTRANSFER, true);
77+
$this->curl->get('https://api.github.com/repos/TrueLayer/magento2/releases');
78+
$responseStatus = $this->curl->getStatus();
79+
if ($responseStatus !== 200) {
80+
$this->logger->error('Plugin version check failed, could not retrieve releases from github api', [
81+
'response_status' => $responseStatus,
82+
'response_body' => $this->curl->getBody()
83+
]);
84+
return false;
85+
}
86+
$response = $this->curl->getBody();
87+
try {
88+
$releases = json_decode($response, true, JSON_THROW_ON_ERROR);
89+
} catch (\Exception $e) {
90+
$this->logger->error('Plugin version check failed, json_decode error', [
91+
'response_body' => $response,
92+
'json_exception' => $e->getMessage()
93+
]);
94+
return false;
95+
}
96+
foreach ($releases as $release) {
97+
if (!$release['draft'] && !$release['prerelease']) {
98+
$latestRelease = $release;
99+
break;
100+
}
101+
}
102+
if (!isset($latestRelease)) {
103+
$this->logger->error('Plugin version check failed, no valid release in github api response');
104+
return false;
105+
}
106+
$latestVersion = ltrim($latestRelease['name'], 'v');
107+
return $latestVersion;
108+
}
109+
110+
private function getCurlVersion()
111+
{
112+
$curlVersion = curl_version();
113+
if (is_array($curlVersion) && array_key_exists('version', $curlVersion)) {
114+
$curlVersion = $curlVersion['version'];
115+
} else {
116+
$curlVersion = 'unknown';
117+
}
118+
return $curlVersion;
70119
}
71120
}

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
66
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [v2.4.0] - 2024-11-06
9+
10+
### Added
11+
12+
- A notice will appear on the settings page of the plugin if a newer version of the plugin is available.
13+
- Added "Magento Order Increment ID" to payment metadata when creating the payment in Truelayer.
14+
- PSR-16 cache adapter
15+
- Automatically generate cache encryption key
16+
17+
### Changed
18+
19+
- Using constant filename new uploaded private keys
20+
- Increased PHP dependency version
21+
- Increased TrueLayer PHP Client dependency version
22+
23+
### Fixed
24+
25+
- Potential security issue when deleting a private key
26+
827
## [v2.3.0] - 2024-09-27
928

1029
### Added

Controller/Adminhtml/Credentials/Check.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ private function getCredentials(): array
171171
'client_id' => $clientId,
172172
'client_secret' => $clientSecret,
173173
'private_key' => $this->getPrivateKeyPath($configCredentials),
174-
'key_id' => $keyId
174+
'key_id' => $keyId,
175+
'cache_encryption_key' => $configCredentials['cache_encryption_key']
175176
]
176177
];
177178
}

0 commit comments

Comments
 (0)