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
130 changes: 0 additions & 130 deletions .github/scripts/release-notes.py

This file was deleted.

68 changes: 21 additions & 47 deletions .github/workflows/auto-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ jobs:
runs-on: ${{ vars.RUNNER_STANDARD }}
steps:
- uses: actions/checkout@v4
with:
# Need full history so `.github/scripts/release-notes.py` can walk
# every commit not yet on main when building the preview
# release notes.
fetch-depth: 0

# Use the org GitHub App token — PRs opened with the default
# GITHUB_TOKEN do not trigger downstream workflows, so the
Expand All @@ -31,55 +26,34 @@ jobs:
client-id: ${{ vars.TWO_INC_APP_CLIENT_ID }}
private-key: ${{ secrets.TWO_INC_APP_PRIVATE_KEY }}

- name: Build preview of next release notes
id: preview
- name: Ensure open PR develop → main
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
existing=$(gh pr list --base main --head develop --state open --json number --jq '.[0].number // ""')
if [ -n "$existing" ]; then
echo "PR #$existing already open — nothing to do."
exit 0
fi
# No-op when develop has nothing ahead of main. Happens
# right after a merge-back fast-forwards develop to match
# main — there's no diff for `gh pr create`, which would
# otherwise fail with "No commits between main and develop"
# and leave a red check on the auto-PR workflow.
ahead=$(gh api "repos/${REPO}/compare/main...develop" --jq '.ahead_by')
echo "ahead=$ahead" >> "$GITHUB_OUTPUT"
if [ "$ahead" = "0" ]; then
echo "develop has no commits ahead of main — nothing to sync."
exit 0
fi

# release-notes.py is the same script release.yml uses to
# render the GitHub Release page, so this preview matches
# what will actually ship when the sync PR merges.
# Use origin/main since actions/checkout only creates the
# workflow's own ref as a local branch — `main` alone
# wouldn't resolve here.
level=$(.github/scripts/release-notes.py "origin/main..HEAD" notes.md)

{
echo "Rolling sync PR opened by \`.github/workflows/auto-pr.yml\`. Merging this PR fires \`release.yml\` on \`main\` (auto bump + tag + GitHub Release) and \`merge-back.yml\` (fast-forwards \`develop\` to match)."
echo
echo "Predicted bump: **${level}** — based on the commits below."
echo
cat notes.md
echo
echo "_Close this PR manually if you need to skip a sync window._"
} > body.md

echo "--- body.md preview ---"
cat body.md

- name: Ensure open PR with current preview body
if: steps.preview.outputs.ahead != '0'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
set -euo pipefail
existing=$(gh pr list --base main --head develop --state open --json number --jq '.[0].number // ""')
if [ -n "$existing" ]; then
echo "Updating PR #$existing body with refreshed preview..."
gh pr edit "$existing" --body-file body.md
else
gh pr create \
--base main \
--head develop \
--title "chore: sync develop → main" \
--body-file body.md
fi
gh pr create \
--base main \
--head develop \
--title "chore: sync develop → main" \
--body "$(cat <<'EOF'
Automated rolling sync PR opened by `.github/workflows/auto-pr-develop-to-main.yml`.

Merges everything currently on `develop` into `main`. Auto-updates as new commits land on `develop`. Close manually if you need to skip a sync window.
EOF
)"
39 changes: 27 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,23 @@ jobs:
docker run --detach --name magento-project-community-edition \
michielgerritsen/magento-project-community-edition:${{ matrix.php_image }}-magento${{ matrix.magento }}

- name: Create branch for Composer (composer rejects published versions on a feature branch)
- name: Upload tracked source into container
# Ship only tracked files — avoids leaking .git/, dotfiles,
# or any untracked working-tree state into the CI container.
# `git ls-files | tar` is preferred over `git archive` here
# because the latter honours .gitattributes export-ignore
# and would strip phpstan.neon / phpunit.xml / Test/ which CI
# needs but the release zip does not.
run: |
git checkout -b continuous-integration-test-branch
sed -i '/version/d' ./composer.json
docker exec magento-project-community-edition mkdir -p /data/extensions/magento-plugin
git ls-files -z | tar --null -cf - -T - | docker exec -i magento-project-community-edition tar -x -C /data/extensions/magento-plugin

- name: Upload code into container
run: docker cp "$(pwd)" magento-project-community-edition:/data/extensions/

- name: Install extension
- name: Install extension from uploaded source
run: |
docker exec magento-project-community-edition \
composer require two-inc/magento2:@dev --no-plugins
composer config repositories.local path '/data/extensions/*'
docker exec magento-project-community-edition \
composer require 'two-inc/magento2:*@dev' --no-plugins

- name: Activate extension
run: |
Expand Down Expand Up @@ -169,13 +174,23 @@ jobs:
docker run --detach --name magento-project-community-edition \
michielgerritsen/magento-project-community-edition:${{ matrix.php_image }}-magento${{ matrix.magento }}

- name: Upload code into container
run: docker cp "$(pwd)" magento-project-community-edition:/data/extensions/
- name: Upload tracked source into container
# Ship only tracked files — avoids leaking .git/, dotfiles,
# or any untracked working-tree state into the CI container.
# `git ls-files | tar` is preferred over `git archive` here
# because the latter honours .gitattributes export-ignore
# and would strip phpstan.neon / phpunit.xml / Test/ which CI
# needs but the release zip does not.
run: |
docker exec magento-project-community-edition mkdir -p /data/extensions/magento-plugin
git ls-files -z | tar --null -cf - -T - | docker exec -i magento-project-community-edition tar -x -C /data/extensions/magento-plugin

- name: Install extension
- name: Install extension from uploaded source
run: |
docker exec magento-project-community-edition \
composer require two-inc/magento2:@dev --no-plugins
composer config repositories.local path '/data/extensions/*'
docker exec magento-project-community-edition \
composer require 'two-inc/magento2:*@dev' --no-plugins

- name: Run setup:di:compile
run: |
Expand Down
62 changes: 54 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ jobs:
git config user.email "${{ vars.TWO_INC_APP_ID }}+two-inc-app[bot]@users.noreply.github.com"

- name: Decide bump level + build release notes
# Both the bump level and the markdown notes come out of
# .github/scripts/release-notes.py — the same script auto-pr.yml
# uses to render the rolling sync PR's preview, so the
# GitHub Release page exactly matches what was previewed
# before merge.
# Single pass over `<previous-numeric-tag>..HEAD`:
# - Buckets each non-merge commit into Breaking / Features /
# Fixes / Internals / Other based on its conventional-commit
# type, with optional Linear ticket prefix (e.g. CET-123/feat:).
# - Writes the bucketed list to release-notes.md so the GitHub
# Release page reflects exactly what triggered the bump level
# (any Breaking entries → major; any Features → minor; else
# patch). Reading the notes makes the bump-level decision
# visible without having to look at the workflow log.
if: steps.gate.outputs.skip == '0'
id: bump
run: |
Expand All @@ -113,10 +117,52 @@ jobs:
range="HEAD"
fi

level=$(.github/scripts/release-notes.py "$range" release-notes.md)
: > release-notes.md
: > /tmp/breaking
: > /tmp/features
: > /tmp/fixes
: > /tmp/internals
: > /tmp/other

while IFS=$'\t' read -r sha subject; do
line="- ${subject} (${sha})"
if echo "$subject" | grep -qE '^([A-Z]+-[0-9]+/)?[a-z]+(\([^)]+\))?!:|^BREAKING CHANGE:'; then
echo "$line" >> /tmp/breaking
elif echo "$subject" | grep -qE '^([A-Z]+-[0-9]+/)?feat(\([^)]+\))?:'; then
echo "$line" >> /tmp/features
elif echo "$subject" | grep -qE '^([A-Z]+-[0-9]+/)?fix(\([^)]+\))?:'; then
echo "$line" >> /tmp/fixes
elif echo "$subject" | grep -qE '^([A-Z]+-[0-9]+/)?(chore|refactor|ci|docs|test|build|perf|style)(\([^)]+\))?:'; then
echo "$line" >> /tmp/internals
else
echo "$line" >> /tmp/other
fi
done < <(git log "$range" --no-merges --format='%h%x09%s')

# Bump level is the highest-severity bucket that's non-empty.
if [ -s /tmp/breaking ]; then
level=major
elif [ -s /tmp/features ]; then
level=minor
else
level=patch
fi
echo "level=$level" >> "$GITHUB_OUTPUT"
echo "prev=$prev" >> "$GITHUB_OUTPUT"
echo "Selected bump level: $level (range: $range)"

# Render notes — only print sections that have entries.
{
[ -s /tmp/breaking ] && { echo "## ⚠️ Breaking changes"; cat /tmp/breaking; echo; }
[ -s /tmp/features ] && { echo "## 🚀 Features"; cat /tmp/features; echo; }
[ -s /tmp/fixes ] && { echo "## 🐛 Fixes"; cat /tmp/fixes; echo; }
[ -s /tmp/internals ] && { echo "## 🧰 Internals"; cat /tmp/internals; echo; }
[ -s /tmp/other ] && { echo "## Other"; cat /tmp/other; echo; }
} > release-notes.md
# Stash the previous tag so the post-bump step can append a
# "Full diff" link with the proper <prev>..<new> range —
# the new tag isn't known yet at this point.
echo "prev=$prev" >> "$GITHUB_OUTPUT"

echo "--- release-notes.md preview ---"
cat release-notes.md

Expand All @@ -143,7 +189,7 @@ jobs:
- name: Append full-diff link to release notes
# Now that the new version is known we can render a proper
# <prev>..<new> link instead of leaving the right-hand side
# blank (the prior shape rendered as "abn-1.13.2..").
# blank (the prior shape rendered as "<prefix>-1.13.2..").
if: steps.gate.outputs.skip == '0'
env:
PREV: ${{ steps.bump.outputs.prev }}
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ composer.lock
# Python
*.venv
.phpunit.result.cache
.fork-compare/
.serena/
agent-notes/
upstream-backport-brief.md
plans/
Loading
Loading