Skip to content

Commit 9b33704

Browse files
Update CLI to use new GITHUB_OUTPUT environment (#30)
* Update empty github_output.txt * Prepare Tests for GITHUB_OUTPUT * Update Tests * Use new GITHUB_OUTPUT syntax when available * Enable GITHUB_OUTPUT by default * Support old syntax until end of 2022 * Make method private
1 parent 8c0aae8 commit 9b33704

File tree

5 files changed

+113
-37
lines changed

5 files changed

+113
-37
lines changed

app/Support/GitHubActionsOutput.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,34 @@ class GitHubActionsOutput extends MessageBag
1212
public function render(OutputStyle $output): void
1313
{
1414
foreach ($this->messages() as $key => $message) {
15-
$output->text(sprintf("::set-output name=%s::%s", $key, head($message)));
15+
$value = head($message);
16+
17+
if ($this->hasGithubOutputEnvironment()) {
18+
$this->setOutput($key, $value);
19+
}
20+
21+
// Set output variables using old syntax for compatibility with older versions of GitHub Actions runner.
22+
// Stops working in 2023.
23+
if (now()->year < 2023) {
24+
$output->text(sprintf("::set-output name=%s::%s", $key, $value));
25+
}
1626
}
1727
}
28+
29+
private function setOutput($name, $value): void
30+
{
31+
$pathToGitHubOutput = getenv('GITHUB_OUTPUT');
32+
$gitHubOutput = file_get_contents($pathToGitHubOutput);
33+
34+
$gitHubOutput .= "$name=$value\n";
35+
36+
file_put_contents($pathToGitHubOutput, $gitHubOutput, FILE_APPEND | LOCK_EX);
37+
}
38+
39+
private function hasGithubOutputEnvironment(): bool
40+
{
41+
$gitHubOutput = getenv('GITHUB_OUTPUT');
42+
43+
return ! empty($gitHubOutput);
44+
}
1845
}

tests/CreatesApplication.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
trait CreatesApplication
1010
{
11+
public readonly string $gitHubOutputTestfile;
12+
1113
/**
1214
* Creates the application.
1315
*
@@ -17,6 +19,10 @@ public function createApplication()
1719
{
1820
$app = require __DIR__.'/../bootstrap/app.php';
1921

22+
$this->gitHubOutputTestfile = base_path('tests/github_output.txt');
23+
24+
putenv("GITHUB_OUTPUT=$this->gitHubOutputTestfile");
25+
2026
$app->make(Kernel::class)->bootstrap();
2127

2228
return $app;

tests/Feature/UpdateCommandTest.php

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog.md',
2020
'--release-date' => '2021-02-01',
2121
])
22-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog.md'))
23-
->assertSuccessful();
22+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog.md'))
23+
->assertSuccessful();
2424
});
2525

2626
it('outputs RELEASE_COMPARE_URL and UNRELEASED_COMPARE_URL for GitHub Actions in CI environment', function () {
@@ -41,17 +41,43 @@
4141
'--release-date' => '2021-02-01',
4242
'--github-actions-output' => true,
4343
])
44-
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'RELEASE_COMPARE_URL', 'https://github.com/org/repo/compare/v0.1.0...v1.0.0'))
45-
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'RELEASE_URL_FRAGMENT', '#v100---2021-02-01'))
46-
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'UNRELEASED_COMPARE_URL', 'https://github.com/org/repo/compare/v1.0.0...HEAD'))
47-
->assertSuccessful();
44+
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'RELEASE_COMPARE_URL', 'https://github.com/org/repo/compare/v0.1.0...v1.0.0'))
45+
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'RELEASE_URL_FRAGMENT', '#v100---2021-02-01'))
46+
->expectsOutputToContain(sprintf("::set-output name=%s::%s", 'UNRELEASED_COMPARE_URL', 'https://github.com/org/repo/compare/v1.0.0...HEAD'))
47+
->assertSuccessful();
48+
})->skip(function () {
49+
return now()->year > 2022;
50+
});
51+
52+
it('outputs RELEASE_COMPARE_URL and UNRELEASED_COMPARE_URL to GITHUB_OUTPUT environment', function () {
53+
$this->artisan('update', [
54+
'--release-notes' => <<<MD
55+
### Added
56+
- New Feature A
57+
- New Feature B
58+
59+
### Changed
60+
- Update Feature C
61+
62+
### Removes
63+
- Remove Feature D
64+
MD,
65+
'--latest-version' => 'v1.0.0',
66+
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog.md',
67+
'--release-date' => '2021-02-01',
68+
'--github-actions-output' => true,
69+
])->assertSuccessful();
70+
71+
$this->assertGitHubOutputContains('RELEASE_COMPARE_URL', 'https://github.com/org/repo/compare/v0.1.0...v1.0.0');
72+
$this->assertGitHubOutputContains('RELEASE_URL_FRAGMENT', '#v100---2021-02-01');
73+
$this->assertGitHubOutputContains('UNRELEASED_COMPARE_URL', 'https://github.com/org/repo/compare/v1.0.0...HEAD');
4874
});
4975

5076
it('throws error if latest-version is missing', function () {
5177
$this->artisan('update', [
5278
'--release-notes' => '::release-notes::',
53-
])
54-
->assertFailed();
79+
])
80+
->assertFailed();
5581
})->throws(InvalidArgumentException::class, 'No latest-version option provided. Abort.');
5682

5783
it('uses current date for release date if no option is provieded', function () {
@@ -73,8 +99,8 @@
7399
'--latest-version' => 'v1.0.0',
74100
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog.md',
75101
])
76-
->expectsOutput($expectedOutput)
77-
->assertSuccessful();
102+
->expectsOutput($expectedOutput)
103+
->assertSuccessful();
78104
});
79105

80106
it('uses current date for release date if option is empty', function () {
@@ -97,8 +123,8 @@
97123
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog.md',
98124
'--release-date' => '',
99125
])
100-
->expectsOutput($expectedOutput)
101-
->assertSuccessful();
126+
->expectsOutput($expectedOutput)
127+
->assertSuccessful();
102128
});
103129

104130
it('places given release notes in correct position in given markdown changelog when no unreleased heading is available', function () {
@@ -118,8 +144,8 @@
118144
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog-without-unreleased.md',
119145
'--release-date' => '2021-02-01',
120146
])
121-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-unreleased.md'))
122-
->assertSuccessful();
147+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-unreleased.md'))
148+
->assertSuccessful();
123149
});
124150

125151
it('places given release notes in correct position in given markdown changelog when no heading is available', function () {
@@ -139,8 +165,8 @@
139165
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog-without-headings.md',
140166
'--release-date' => '2021-02-01',
141167
])
142-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-headings.md'))
143-
->assertSuccessful();
168+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-headings.md'))
169+
->assertSuccessful();
144170
});
145171

146172
it('places given release notes in correct position even if changelog is empty besides an unreleased heading', function () {
@@ -160,8 +186,8 @@
160186
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog-empty-with-unreleased.md',
161187
'--release-date' => '2021-02-01',
162188
])
163-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-empty-with-unreleased.md'))
164-
->assertSuccessful();
189+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-empty-with-unreleased.md'))
190+
->assertSuccessful();
165191
});
166192

167193
it('uses compare-url-target option in unreleased heading url', function () {
@@ -182,8 +208,8 @@
182208
'--release-date' => '2021-02-01',
183209
'--compare-url-target-revision' => '1.x',
184210
])
185-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-custom-compare-url-target.md'))
186-
->assertSuccessful();
211+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-custom-compare-url-target.md'))
212+
->assertSuccessful();
187213
});
188214

189215
it('shows warning if version already exists in the changelog', function () {
@@ -204,8 +230,8 @@
204230
'--release-date' => '2021-02-01',
205231
'--compare-url-target-revision' => '1.x',
206232
])
207-
->expectsOutput('CHANGELOG was not updated as release notes for v0.1.0 already exist.')
208-
->assertSuccessful();
233+
->expectsOutput('CHANGELOG was not updated as release notes for v0.1.0 already exist.')
234+
->assertSuccessful();
209235
});
210236

211237
it('uses existing content between unreleased and previous version heading as release notes if release notes are empty', function () {
@@ -216,8 +242,8 @@
216242
'--release-date' => '2021-02-01',
217243
'--compare-url-target-revision' => '1.x',
218244
])
219-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-unreleased-notes.md'))
220-
->assertSuccessful();
245+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-unreleased-notes.md'))
246+
->assertSuccessful();
221247
});
222248

223249
it('uses existing content between unreleased and previous version heading as release notes if release notes option is not provided', function () {
@@ -227,8 +253,8 @@
227253
'--release-date' => '2021-02-01',
228254
'--compare-url-target-revision' => '1.x',
229255
])
230-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-unreleased-notes.md'))
231-
->assertSuccessful();
256+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-unreleased-notes.md'))
257+
->assertSuccessful();
232258
});
233259

234260
it('nothing happens if no release notes have been given and no unreleased heading can be found', function () {
@@ -238,8 +264,8 @@
238264
'--release-date' => '2021-02-01',
239265
'--compare-url-target-revision' => '1.x',
240266
])
241-
->expectsOutput('Release Notes were not provided. Pass them through the `--release-notes`-option.')
242-
->assertFailed();
267+
->expectsOutput('Release Notes were not provided. Pass them through the `--release-notes`-option.')
268+
->assertFailed();
243269
});
244270

245271
test('it shows warning if changelog is empty and content can not be placed', function () {
@@ -259,8 +285,8 @@
259285
'--path-to-changelog' => __DIR__ . '/../Stubs/empty-changelog.md',
260286
'--compare-url-target-revision' => 'HEAD',
261287
])
262-
->expectsOutput('Release notes could not be placed. Is the CHANGELOG empty? Does it contain at least one heading?')
263-
->assertFailed();
288+
->expectsOutput('Release notes could not be placed. Is the CHANGELOG empty? Does it contain at least one heading?')
289+
->assertFailed();
264290
});
265291

266292
test('it automatically shifts heading levels to be level 3 headings to fit into the existing changelog', function ($releaseNotes) {
@@ -270,8 +296,8 @@
270296
'--path-to-changelog' => __DIR__ . '/../Stubs/base-changelog.md',
271297
'--release-date' => '2021-02-01',
272298
])
273-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-shifted-headings.md'))
274-
->assertSuccessful();
299+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-shifted-headings.md'))
300+
->assertSuccessful();
275301
})->with([
276302
'starts with h1' => <<<MD
277303
# Added
@@ -315,8 +341,8 @@
315341
'--release-date' => '2021-02-01',
316342
'--heading-text' => '::heading-text::',
317343
])
318-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-heading-text.md'))
319-
->assertSuccessful();
344+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-with-heading-text.md'))
345+
->assertSuccessful();
320346
});
321347

322348
it('heading-text option allows user to use different heading text than latest-version when changelog does not contain unreleased heading', function () {
@@ -337,8 +363,8 @@
337363
'--release-date' => '2021-02-01',
338364
'--heading-text' => '::heading-text::',
339365
])
340-
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-unreleased-with-heading-text.md'))
341-
->assertSuccessful();
366+
->expectsOutput(file_get_contents(__DIR__ . '/../Stubs/expected-changelog-without-unreleased-with-heading-text.md'))
367+
->assertSuccessful();
342368
});
343369

344370
it('allows release date to be in any given format', function () {

tests/TestCase.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,21 @@
99
abstract class TestCase extends BaseTestCase
1010
{
1111
use CreatesApplication;
12+
13+
protected function tearDown(): void
14+
{
15+
file_put_contents($this->gitHubOutputTestfile, '');
16+
17+
parent::tearDown();
18+
}
19+
20+
public function assertGitHubOutputContains($name, $value)
21+
{
22+
$this->assertStringContainsString("$name=$value", file_get_contents($this->gitHubOutputTestfile));
23+
}
24+
25+
public function assertGitHubOutputDoesntContain($name, $value)
26+
{
27+
$this->assertStringNotContainsString("$name=$value", file_get_contents($this->gitHubOutputTestfile));
28+
}
1229
}

tests/github_output.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)