Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@acoulton
Copy link
Contributor

Relates to #260 and #227

I have rewritten the update_cucumber script and the github actions workflow for this, as detailed in the commit messages.

I've tested the script itself locally all the way up to the current cucumber/gherkin release and it is working as expected and producing the right composer patches and commit messages.

I've tested as much of the github actions flow as I feasibly can in an external repo. There's obviously the chance there are issues in the wiring up (especially of the custom github app / token permissions etc) but for what this is I think it's easier if we merge it and troubleshoot anything that comes up once it's running.

As of 25.0.0, cucumber reorganised their repositories so that all the
Gherkin parsers plus the testdata, translations and other resources now
live in a monorepo at cucumber/gherkin.

Our dependency and build has therefore not picked up recent releases.

There is also now an official PHP library on packagist at
`cucumber/gherkin`, so I have renamed our custom dependency to
`cucumber/gherkin-monorepo` to avoid confusion.

Note that this commit does not fix the build/update tooling, which
I will tackle separately.
@acoulton
Copy link
Contributor Author

Also to note that both the actions scripts I've added (which I couldn't find direct solutions for on Marketplace) are things we actually need at work. Once we see them working, I'll probably look at extracting them to standalone actions, rather than permanently having them as scripts in this repo.

id: check-existing-pr
uses: actions/github-script@v7
with:
script: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realise this is quite hard to follow in unified diff format. It's much easier to view in split diff.

This needs to run before the checkout, because it controls which branch we pull - hence why it is inline in the action.yml rather than a separate script. I envisage this eventually becoming a standalone action.

id: changelog
run: bin/cucumber_changelog ${{ steps.cucumber.outputs.cucumber_version }}
if: steps.cucumber.outputs.cucumber_version
if (pr) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We first check to see if there's an existing cucumber-update-* branch in this repo with an open PR. If there is, that will be checked out and the next cucumber update (if any) applied to the same branch.

If not, we create a new branch based off master. We use a unique suffix on the branch name to avoid any conflict with an old update (if e.g. a previous PR was merged/closed but the branch was not deleted).

app-id: ${{ vars.GHERKIN_UPDATER_APP_ID }}
private-key: ${{ secrets.GHERKIN_UPDATER_APP_KEY }}

- run: .github/commit-and-push-gherkin-update.sh
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to use the current peter-evans/create-pull-request action because that is explicitly designed to always create a single new commit off the main branch and force push it. If there are multiple gherkin releases before we get round to merging the branch, I would much prefer to see these as separate updates each with their own build results etc.

There are other "auto commit and push" actions, but they all have limitations / design decisions that made them not quite right for this. For example, they often use the github token provided in the initial actions/checkout step - but in our case it's cleaner and more secure to only create the custom app token right at the end, if we know we have something to push.

BRANCH_NAME: ${{ steps.check-existing-pr.commit_branch }}
COMMIT_MSG: ${{ steps.cucumber.outputs.commit_msg }}
PR_EXISTS: ${{ steps.check-existing-pr.outputs.exists }}
PR_TITLE: Update to cucumber/gherkin ${{ steps.cucumber.outputs.cucumber_version }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title will always be updated to the latest Gherkin release it includes

echo "Authenticating and pushing"
# This will reconfigure git to push with the token provided in the GH_TOKEN env var
gh auth setup-git
git push -u origin "$BRANCH_NAME"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design decision: the update branches will be in the main Behat/Gherkin repository (as they were before). We'll need to relax the branch protection rules to allow us to delete cucumber-update-* branches after they're merged. This does mean they'll appear in packagist.

Alternatively we could create a Behat/Gherkin-Automation-PRS repo as a fork and configure our github app with the permissions to push the branch there instead. However that complicates things a bit and I think it's simpler to keep everything together?

This has been broken since cucumber reorganised their repositories. As
well as moving to a new repository, the tagging and changelog structure
is different. There were also some issues with the old scripts - e.g.
the changelog was not properly escaped in the PR body (see Behat#255 for an
example of broken content & links).

I have rewritten the flow so that:

* We use the GitHub API to fetch release details and changelogs, rather
  than trying to parse the changelog markdown file.
* We only bump one Gherkin release per workflow run (so that we can see
  clearly which release causes tests to fail, if any).
* We include the Gherkin release details in the commit message (the old
  script could bump multiple releases in a single commit but only showed
  the most recent changelog in the PR body, which was misleading).
* If there is already a PR open, we append subsequent releases to the
  same PR.
So that they trigger builds as expected. This also means we can
lock down the default permissions for the GITHUB_TOKEN that is
used for the initial phase of the job, and only escalate to a
token with write access if/when we have something to commit.
@acoulton acoulton force-pushed the maint-cucumber-update branch from 3cc5bdf to 16731b5 Compare April 24, 2025 08:06
Copy link
Contributor

@carlos-granados carlos-granados left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @acoulton, great job. As you said I think that the best course of action will be to merge this, test it and fix it if any issues are found

@acoulton acoulton merged commit 04dfa0f into Behat:master Apr 24, 2025
8 checks passed
@acoulton acoulton deleted the maint-cucumber-update branch April 24, 2025 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants