Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 22 additions & 19 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
name: Release

on:
pull_request_target:
types: [closed]
push:
branches:
- main

permissions:
contents: write

concurrency:
group: release-${{ github.event.pull_request.base.ref }}
group: release-${{ github.ref_name }}
cancel-in-progress: false

jobs:
release:
if: >
github.event.pull_request.merged == true &&
github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-latest

steps:
- name: Check out merged commit
- name: Check out pushed commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
ref: ${{ github.sha }}
fetch-depth: 0

- name: Fetch tags
Expand All @@ -31,13 +29,12 @@ jobs:
- name: Determine CalVer tag
id: calver
env:
MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }}
MERGED_AT: ${{ github.event.pull_request.merged_at }}
RELEASE_COMMIT_SHA: ${{ github.sha }}
run: |
set -euo pipefail

existing_tag="$(
git tag --points-at "$MERGE_COMMIT_SHA" |
git tag --points-at "$RELEASE_COMMIT_SHA" |
grep -E '^v[0-9]{2}\.[0-9]{2}\.[0-9]{2}\.[0-9]+$' |
sort -V |
tail -n 1 || true
Expand All @@ -46,7 +43,8 @@ jobs:
if [ -n "$existing_tag" ]; then
tag="$existing_tag"
else
base="$(date -u -d "$MERGED_AT" +'%y.%m.%d')"
commit_timestamp="$(git show -s --format=%cI "$RELEASE_COMMIT_SHA")"
base="$(date -u -d "$commit_timestamp" +'%y.%m.%d')"
max_suffix=0

while IFS= read -r existing; do
Expand All @@ -67,31 +65,36 @@ jobs:

- name: Create and push tag
env:
MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }}
RELEASE_COMMIT_SHA: ${{ github.sha }}
TAG: ${{ steps.calver.outputs.tag }}
run: |
set -euo pipefail

if git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null 2>&1; then
remote_sha="$(git rev-list -n 1 "$TAG")"
if [ "$remote_sha" = "$MERGE_COMMIT_SHA" ]; then
remote_refs="$(git ls-remote --tags origin "refs/tags/$TAG" "refs/tags/$TAG^{}")"
remote_sha="$(printf '%s\n' "$remote_refs" | awk '$2 ~ /\^\{\}$/ { print $1; exit }')"
if [ -z "$remote_sha" ]; then
remote_sha="$(printf '%s\n' "$remote_refs" | awk 'NF { print $1; exit }')"
fi

if [ "$remote_sha" = "$RELEASE_COMMIT_SHA" ]; then
echo "Tag $TAG already exists on origin and points to the expected commit"
exit 0
fi

echo "Error: Tag $TAG already exists on origin but points to $remote_sha instead of $MERGE_COMMIT_SHA"
echo "Error: Tag $TAG already exists on origin but points to $remote_sha instead of $RELEASE_COMMIT_SHA"
exit 1
fi

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG" "$MERGE_COMMIT_SHA" -m "Release $TAG"
git tag -a "$TAG" "$RELEASE_COMMIT_SHA" -m "Release $TAG"
git push origin "refs/tags/$TAG"

- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
MERGE_COMMIT_SHA: ${{ github.event.pull_request.merge_commit_sha }}
RELEASE_COMMIT_SHA: ${{ github.sha }}
TAG: ${{ steps.calver.outputs.tag }}
run: |
set -euo pipefail
Expand All @@ -102,6 +105,6 @@ jobs:
fi

gh release create "$TAG" \
--target "$MERGE_COMMIT_SHA" \
--target "$RELEASE_COMMIT_SHA" \
--generate-notes \
--title "$TAG"
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ docker-compose up -d

Default local ports:

- MySQL/MariaDB on `127.0.0.1:3306`
- PostgreSQL on `127.0.0.1:5432`
- MySQL/MariaDB on host port `3306`
- PostgreSQL on host port `5432`

## Running checks

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The repository includes:
- PHPStan static analysis
- PHP-CS-Fixer formatting checks
- GitHub Actions CI for pushes and pull requests
- Automatic `vYY.MM.DD.n` CalVer tags and GitHub releases for merged PRs to `main`
- Automatic `vYY.MM.DD.n` CalVer tags and GitHub releases for pushes to `main`

## Learn more

Expand Down
11 changes: 11 additions & 0 deletions tests/Model/CategoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,21 @@ public function setUp(): void
Freshsauce\Model\Model::execute('TRUNCATE TABLE "categories" RESTART IDENTITY');
} elseif (self::$driverName === 'sqlite') {
Freshsauce\Model\Model::execute('DELETE FROM `categories`');
$this->resetSqliteSequenceIfPresent();
}
}

private function resetSqliteSequenceIfPresent(): void
{
try {
Freshsauce\Model\Model::execute(
'DELETE FROM `' . self::SQLITE_SEQUENCE_TABLE . '` WHERE `name` = ?',
['categories']
);
} catch (\PDOException $e) {
if (strpos($e->getMessage(), 'no such table: ' . self::SQLITE_SEQUENCE_TABLE) === false) {
throw $e;
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion tests/Model/SqliteModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@ public static function setUpBeforeClass(): void
protected function setUp(): void
{
App\Model\SqliteCategory::execute('DELETE FROM `categories`');
App\Model\SqliteCategory::execute('DELETE FROM sqlite_sequence WHERE name = ?', ['categories']);
$this->resetSqliteSequenceIfPresent();
}

private function resetSqliteSequenceIfPresent(): void
{
try {
App\Model\SqliteCategory::execute('DELETE FROM sqlite_sequence WHERE name = ?', ['categories']);
} catch (\PDOException $e) {
if (strpos($e->getMessage(), 'no such table: sqlite_sequence') === false) {
throw $e;
}
}
}

public function testSqliteInsertWithDirtyFields(): void
Expand Down