diff --git a/.github/workflows/arginfo-files.yml b/.github/workflows/arginfo-files.yml index f85aeaad6..c0b0a8c0e 100644 --- a/.github/workflows/arginfo-files.yml +++ b/.github/workflows/arginfo-files.yml @@ -32,7 +32,6 @@ jobs: uses: "shivammathur/setup-php@v2" with: php-version: "${{ matrix.php-version }}" - tools: "phpize" - name: "Run phpize" run: phpize diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index c7a3f0cb4..c1ecb3309 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -32,7 +32,6 @@ jobs: uses: "shivammathur/setup-php@v2" with: php-version: "${{ matrix.php-version }}" - tools: "phpize" - name: "Configure driver" run: .github/workflows/configure.sh diff --git a/.github/workflows/linux/build/action.yml b/.github/workflows/linux/build/action.yml new file mode 100644 index 000000000..a66462268 --- /dev/null +++ b/.github/workflows/linux/build/action.yml @@ -0,0 +1,23 @@ +name: "Linux Build" +description: "Builds the driver" +inputs: + version: + description: "PHP version to build for" + required: true +runs: + using: composite + steps: + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ inputs.version }}" + # Only install required extensions + extensions: "none,date,json,spl,standard,xml" + + - name: "Configure driver" + run: .github/workflows/configure.sh + shell: bash + + - name: "Build driver" + run: "make all" + shell: bash diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml new file mode 100644 index 000000000..b913658c2 --- /dev/null +++ b/.github/workflows/package-release.yml @@ -0,0 +1,110 @@ +name: "Package Release" +run-name: "Package Release ${{ github.ref_name }}" + +on: + push: + tags: + - "*" + +jobs: + build-pecl: + name: "Create PECL package" + runs-on: "ubuntu-latest" + + steps: + - name: "Checkout" + uses: "actions/checkout@v4" + with: + # Manually specify a ref. When actions/checkout is run for a tag without a ref, it looks up the underlying + # commit and specifically fetches this to the refs/tags/ ref, which denies us access to the tag message + ref: ${{ github.ref }} + submodules: true + + - name: "Build Driver" + uses: ./.github/workflows/linux/build + with: + version: "8.3" + + - name: "Write changelog file for packaging" + run: git tag -l ${{ github.ref_name }} --format='%(contents)' > changelog + + # This will fill in the release notes from the previously generated changelog + - name: "Build package.xml" + run: "make package.xml RELEASE_NOTES_FILE=$(pwd)/changelog" + + - name: "Build release archive" + run: "make package" + + # PECL always uses the version for the package name. + # Read it from the version file and store in env to use when uploading artifacts + - name: "Read current package version" + run: echo "PACKAGE_VERSION=$(./bin/update-release-version.php get-version)" >> "$GITHUB_ENV" + + - name: "Install release archive to verify correctness" + run: sudo pecl install mongodb-${{ env.PACKAGE_VERSION }}.tgz + + - name: "Upload artifact" + uses: actions/upload-artifact@v4 + with: + name: mongodb-${{ env.PACKAGE_VERSION }}.tgz + path: mongodb-${{ env.PACKAGE_VERSION }}.tgz + retention-days: 3 + + - name: "Upload release artifact" + run: gh release upload ${{ github.ref_name }} mongodb-${{ env.PACKAGE_VERSION }}.tgz + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-windows: + name: "Create Windows package" + runs-on: windows-2022 + defaults: + run: + shell: cmd + + strategy: + fail-fast: false + matrix: + # Note: keep this in sync with the Windows matrix in windows-tests.yml + php: [ "7.4", "8.0", "8.1", "8.2", "8.3" ] + arch: [ x64, x86 ] + ts: [ ts, nts ] + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: "Build Driver" + id: build-driver + uses: ./.github/workflows/windows/build + with: + version: ${{ matrix.php }} + arch: ${{ matrix.arch }} + ts: ${{ matrix.ts }} + + - name: "Copy DLL and PDB files to CWD" + run: | + cp %BUILD_DIR%\php_mongodb.dll . + cp %BUILD_DIR%\php_mongodb.pdb . + env: + BUILD_DIR: ${{ steps.build-driver.outputs.build-dir }} + + - name: "Upload DLL and PDB files as build artifacts" + uses: actions/upload-artifact@v4 + with: + name: php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }} + path: | + php_mongodb.dll + php_mongodb.pdb + retention-days: 3 + + - name: "Create and upload release artifact" + run: | + set ARCHIVE=php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}.zip + zip %ARCHIVE% php_mongodb.dll php_mongodb.pdb CREDITS CONTRIBUTING.md LICENSE README.md THIRD_PARTY_NOTICES + gh release upload ${{ github.ref_name }} %ARCHIVE% + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..90f4c1569 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,139 @@ +name: "Release New Version" +run-name: "Release ${{ inputs.version }}" + +on: + workflow_dispatch: + inputs: + version: + description: "The version to be released. This is checked for consistency with the branch name and configuration" + required: true + type: "string" + jira-version-number: + description: "JIRA version ID (e.g. 54321)" + required: true + type: "string" + +env: + # TODO: Use different token + GH_TOKEN: ${{ secrets.MERGE_UP_TOKEN }} + GIT_AUTHOR_NAME: "DBX PHP Release Bot" + GIT_AUTHOR_EMAIL: "dbx-php@mongodb.com" + default-release-message: | + The PHP team is happy to announce that version {0} of the [mongodb](https://pecl.php.net/package/mongodb) PHP extension is now available on PECL. + + **Release Highlights** + + TODO: one or more paragraphs describing important changes in this release + + A complete list of resolved issues in this release may be found in [JIRA](https://jira.mongodb.org/secure/ReleaseNote.jspa?version={1}&projectId=12484). + + **Documentation** + + Documentation is available on [PHP.net](https://php.net/set.mongodb). + + **Installation** + + You can either download and install the source manually, or you can install the extension with: + + ``` + pecl install mongodb-{0} + ``` + + or update with: + + ``` + pecl upgrade mongodb-{0} + ``` + + Windows binaries are attached to the GitHub release notes. + +jobs: + prepare-release: + name: "Prepare release" + runs-on: ubuntu-latest + + steps: + - name: "Create release output" + run: echo '🎬 Release process for version ${{ inputs.version }} started by @${{ github.triggering_actor }}' >> $GITHUB_STEP_SUMMARY + + - uses: actions/checkout@v4 + with: + submodules: true + token: ${{ env.GH_TOKEN }} + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + + - name: "Update version information to stable release" + run: ./bin/update-release-version.php to-stable + + - name: "Read current package version" + run: echo "PACKAGE_VERSION=$(./bin/update-release-version.php get-version)" >> "$GITHUB_ENV" + + # Sanity check - the version from the input and the one determined by phongo_version.h need to be the same + - name: "Check version for consistency" + if: ${{ inputs.version != env.PACKAGE_VERSION }} + # We exit with an error to abort the workflow. This is only run if the versions don't match + run: | + echo '❌ Release failed due to version mismatch: expected ${{ inputs.version }}, got ${{ env.PACKAGE_VERSION }} from code' >> $GITHUB_STEP_SUMMARY + exit 1 + + # + # Preliminary checks done - commence the release process + # + + - name: "Set git author information" + run: | + git config user.name "${GIT_AUTHOR_NAME}" + git config user.email "${GIT_AUTHOR_EMAIL}" + + # Create the "Package x.y.z" commit that will be the base of our tag + - name: "Create release commit" + run: git commit -m "Package ${{ env.PACKAGE_VERSION }}" phongo_version.h + + # Create a draft release with a changelog + # TODO: Consider using the API to generate changelog + - name: "Create draft release with generated changelog" + run: gh release create ${{ env.PACKAGE_VERSION }} --target ${{ github.ref_name }} --generate-notes --draft + + - name: "Read changelog from draft release" + run: gh release view ${{ env.PACKAGE_VERSION }} --json body --template '{{ .body }}' >> changelog + + # TODO: Sign tag + - name: "Create release tag" + run: git tag -a -F changelog ${{ env.PACKAGE_VERSION }} + + - name: "Update version information to next patch development release" + run: | + ./bin/update-release-version.php to-next-patch-dev + git commit -m "Back to -dev" phongo_version.h + + # TODO: Manually merge using ours strategy. This avoids merge-up pull requests being created + # Process is: + # 1. switch to next branch (according to merge-up action) + # 2. merge release branch using --strategy=ours + # 3. push next branch + # 4. switch back to release branch, then push + + - name: "Push changes from release branch" + run: git push + + - name: "Prepare release message" + run: | + echo "${{ format(env.default-release-message, env.PACKAGE_VERSION, inputs.jira-version-number) }}" > release-message + cat changelog >> release-message + + # Update release with correct release information + - name: "Update release information" + run: echo "RELEASE_URL=$(gh release edit ${{ env.PACKAGE_VERSION }} --title "${{ env.PACKAGE_VERSION }}" --notes-file release-message)" >> "$GITHUB_ENV" + + # Pushing the release tag starts build processes that then produce artifacts for the release + - name: "Push release tag" + run: git push origin ${{ env.PACKAGE_VERSION }} + + - name: "Set summary" + run: | + echo '🚀 Created tag and drafted release for version [${{ inputs.version }}](${{ env.RELEASE_URL }})' >> $GITHUB_STEP_SUMMARY + echo '✍️ You may now update the release notes and publish the release when ready' >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5bf95ecbb..018ca327f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,7 +54,6 @@ jobs: - name: "Checkout" uses: "actions/checkout@v4" with: - fetch-depth: 2 submodules: true - id: setup-mongodb @@ -63,17 +62,11 @@ jobs: version: ${{ matrix.mongodb-version }} topology: ${{ matrix.topology }} - - name: "Install PHP" - uses: "shivammathur/setup-php@v2" + - name: "Build Driver" + id: build-driver + uses: ./.github/workflows/linux/build with: - php-version: "${{ matrix.php-version }}" - tools: "phpize" - - - name: "Configure driver" - run: .github/workflows/configure.sh - - - name: "Build driver" - run: "make all" + version: ${{ matrix.php-version }} - name: "Run Tests" run: TEST_PHP_ARGS="-q -x --show-diff -g FAIL,XFAIL,BORK,WARN,LEAK,SKIP" make test diff --git a/.github/workflows/windows-release-build.yml b/.github/workflows/windows-release-build.yml deleted file mode 100644 index 423e91499..000000000 --- a/.github/workflows/windows-release-build.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: "Windows Release Build" - -on: - release: - types: [ published ] - -jobs: - windows-release-build: - strategy: - fail-fast: false - matrix: - # Note: keep this in sync with the Windows matrix in windows-tests.yml - php: [ "7.4", "8.0", "8.1", "8.2", "8.3" ] - arch: [ x64, x86 ] - ts: [ ts, nts ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Download DLL and PDB files - uses: dawidd6/action-download-artifact@v3 - with: - workflow: windows-tests.yml - workflow_conclusion: success - commit: ${{ github.sha }} - # Note: keep this in sync with the uploaded artifact name in windows-tests.yml - name: php_mongodb-${{ github.sha }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }} - - - name: Create and attach release archive - run: | - ARCHIVE=php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}.zip - zip $ARCHIVE php_mongodb.dll php_mongodb.pdb CREDITS CONTRIBUTING.md LICENSE README.md THIRD_PARTY_NOTICES - gh release upload $GITHUB_REF_NAME $ARCHIVE - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index 843b755cb..569e47ad7 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -7,8 +7,6 @@ on: - "master" - "feature/*" push: - tags: - - "*" branches: - "v*.*" - "master" @@ -33,53 +31,28 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 2 submodules: true - - name: Prepare build environment - id: prepare-build - uses: ./.github/workflows/windows/prepare-build + - name: "Build Driver" + id: build-driver + uses: ./.github/workflows/windows/build with: version: ${{ matrix.php }} arch: ${{ matrix.arch }} ts: ${{ matrix.ts }} - - name: Build driver - run: nmake /nologo - - name: Cache build artifacts for subsequent builds id: cache-build-artifacts uses: actions/cache/save@v4 with: key: ${{ github.sha }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }} path: | - ${{ steps.prepare-build.outputs.build-dir }}\php_mongodb.dll - ${{ steps.prepare-build.outputs.build-dir }}\php_mongodb.pdb - - - name: Copy DLL and PDB files to CWD - if: ${{ github.event_name == 'push' }} - run: | - cp .github/workflows/get-build-dir.bat . - for /F "usebackq tokens=*" %%i in (`get-build-dir.bat`) do set BUILD_DIR=%%i - echo BUILD_DIR=%BUILD_DIR% - cp %BUILD_DIR%\php_mongodb.dll . - cp %BUILD_DIR%\php_mongodb.pdb . - - - name: Upload DLL and PDB files as build artifacts - if: ${{ github.event_name == 'push' }} - uses: actions/upload-artifact@v4 - with: - name: php_mongodb-${{ github.sha }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }} - path: | - php_mongodb.dll - php_mongodb.pdb - retention-days: 3 + ${{ steps.build-driver.outputs.build-dir }}\php_mongodb.dll + ${{ steps.build-driver.outputs.build-dir }}\php_mongodb.pdb test: name: "Windows Tests" runs-on: windows-2022 - # Run tests only when pushing to a branch. When pushing a tag, we're only interested in building the DLLs. - if: ${{ github.ref_type == 'branch' }} needs: build defaults: run: @@ -97,7 +70,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 2 submodules: true - name: Prepare build environment diff --git a/.github/workflows/windows/build/action.yml b/.github/workflows/windows/build/action.yml new file mode 100644 index 000000000..ec35bf1bc --- /dev/null +++ b/.github/workflows/windows/build/action.yml @@ -0,0 +1,30 @@ +name: "Build DLL files for Windows" +description: "Prepares the PHP build environment for the MongoDB driver" +inputs: + version: + description: "PHP version to build for" + required: true + arch: + description: "The architecture to build for (x64 or x86)" + required: true + ts: + description: "Thread-safety (nts or ts)" + required: true +outputs: + build-dir: + description: "The build directory to be used" + value: ${{ steps.prepare-build-env.outputs.build-dir }} +runs: + using: composite + steps: + - name: Prepare build environment + id: prepare-build-env + uses: ./.github/workflows/windows/prepare-build + with: + version: ${{ inputs.version }} + arch: ${{ inputs.arch }} + ts: ${{ inputs.ts }} + + - name: Build driver + shell: cmd + run: nmake /nologo diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d726a81f..72186ab09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -293,260 +293,3 @@ $ make libmongocrypt-version-current Package dependencies in `config.m4` must also be updated (either manually or with `scripts/update-submodule-sources.php`), as do the sources in the PECL generation script. - -## Releasing - -The following steps outline the release process for both new minor versions (e.g. -releasing the `master` branch as X.Y.0) and patch versions (e.g. releasing the -`vX.Y` branch as X.Y.Z). - -The command examples below assume that the canonical "mongodb" repository has -the remote name "mongodb". You may need to adjust these commands if you've given -the remote another name (e.g. "upstream"). The "origin" remote name was not used -as it likely refers to your personal fork. - -It helps to keep your own fork in sync with the "mongodb" repository (i.e. any -branches and tags on the main repository should also exist in your fork). This -is left as an exercise to the reader. - -### Transition JIRA issues and version - -All issues associated with the release version should be in the "Closed" state -and have a resolution of "Fixed". Issues with other resolutions (e.g. -"Duplicate", "Works as Designed") should be removed from the release version so -that they do not appear in the release notes. - -Check the corresponding ".x" fix version to see if it contains any issues that -are resolved as "Fixed" and should be included in this release version. - -Update the version's release date and status from the -[Manage Versions](https://jira.mongodb.org/plugins/servlet/project-config/PHPC/versions) -page. - -### Update version info - -The PHP driver uses [semantic versioning](http://semver.org/). Do not break -backwards compatibility in a non-major release or your users will kill you. - -Before proceeding, ensure that the `master` branch is up-to-date with all code -changes in this maintenance branch. This is important because we will later -merge the ensuing release commits up to master with `--strategy=ours`, which -will ignore changes from the merged commits. - -Update the version and stability constants in `phongo_version.h`. This should -entail removing the version's "-dev" suffix, changing the stability to -"stable", and increasing the last digit for `PHP_MONGO_VERSION_DESC`: - -```diff --#define PHP_MONGODB_VERSION "1.1.8-dev" --#define PHP_MONGODB_STABILITY "devel" --#define PHP_MONGODB_VERSION_DESC 1,1,8,0 -+#define PHP_MONGODB_VERSION "1.1.8" -+#define PHP_MONGODB_STABILITY "stable" -+#define PHP_MONGODB_VERSION_DESC 1,1,8,1 -``` - -The Makefile targets for creating the PECL package depend on these constants, so -you must rebuild the extension after updating `phongo_version.h`. - -> **Note:** If this is an alpha or beta release, the version string should -> include the X.Y.Z version followed by the stability and an increment. For -> instance, the first beta release in the 1.4.0 series would be "1.4.0beta1". -> Alpha and beta releases use "alpha" and "beta" stability strings, -> respectively. Release candidates (e.g. "1.4.0RC1") also use "beta" stability. -> See [Documenting release stability and API stability](https://pear.php.net/manual/en/guide.developers.package2.stability.php) -> for more information. For each change to the suffixes of -> `PHP_MONGODB_VERSION`, increment the last digit of -> `PHP_MONGODB_VERSION_DESC`. - -### Build PECL package - -Create the PECL package description file with `make package.xml`. This creates -a `package.xml` file from a template. Version, author, and file information will -be filled in, but release notes must be copied manually from JIRA. - -After copying release notes, use `make package` to create the package file (e.g. -`mongodb-X.Y.Z.tgz`) and ensure that it can be successfully installed: - -``` -$ pecl install -f mongodb-X.Y.Z.tgz -``` - -### Update version info - -Commit the modified `phongo_version.h` file and push this change: - -``` -$ git add phongo_version.h -$ git commit -m "Package X.Y.Z" -$ git push mongodb -``` - -> **Note:** Pushing this commit independently from the subsequent "Back to -dev" -> commit will ensure that Windows build artifacts are created for the release. - -### Ensure Windows build artifacts exist - -Windows builds are tested by GitHub Actions. Each successful build for a pushed -commit will produce a build artifact consisting of DLL and PDB files for that -environment (e.g. 8.0-nts-x64). These build artifacts are later used to create -release assets (see: -[windows-release-build.yml](.github/workflows/windows-release-build.yml)). - -Before publishing a release in GitHub, ensure that all Windows builds for the -tag's commit have succeeded and that the necessary build artifacts have been -created. This can be done by examining the build artifacts in the workflow run -summary for the "Package X.Y.Z" commit (i.e. tag target). - -> **Note:** the "published" event applies to both releases and pre-releases. See -> [Events that trigger workflows: release](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release) -> for more details. - -### Tag the release - -Create a tag for the release and push: - -``` -$ git tag -a -m "Release X.Y.Z" X.Y.Z -$ git push mongodb --tags -``` - -### Release PECL package - -The PECL package may be published via the -[Release Upload](https://pecl.php.net/release-upload.php) form. You will have -one chance to confirm the package information after uploading. - -### Update version info back to dev - -After tagging, the version and stability constants in `phongo_version.h` should -be updated back to development status. - -```diff --#define PHP_MONGODB_VERSION "1.1.8" --#define PHP_MONGODB_STABILITY "stable" --#define PHP_MONGODB_VERSION_DESC 1,1,8,1 -+#define PHP_MONGODB_VERSION "1.1.9-dev" -+#define PHP_MONGODB_STABILITY "devel" -+#define PHP_MONGODB_VERSION_DESC 1,1,9,0 -``` - -Commit and push this change: - -``` -$ git commit -m "Back to -dev" phongo_version.h -$ git push mongodb -``` - -> **Note:** If this is an alpha, beta, or RC release, the version string should -> increment the stability sequence instead of the patch version. For example, -> if the constants were originally "1.4.0-dev" and "devel" and then changed to -> "1.4.0beta1" and "beta" for the first beta release, this step would see them -> ultimately changed to "1.4.0beta2-dev" and "devel". - -### Branch management - -#### After releasing a new minor version - -After a new minor version is released (i.e. `master` was tagged), a maintenance -branch should be created for future patch releases: - -``` -$ git checkout -b vX.Y -$ git push mongodb vX.Y -``` - -Update `phongo_version.h` for the `master` branch: - -```diff --#define PHP_MONGODB_VERSION "1.15.1-dev" -+#define PHP_MONGODB_VERSION "1.16.0-dev" - #define PHP_MONGODB_STABILITY "devel" --#define PHP_MONGODB_VERSION_DESC 1,15,1,0 -+#define PHP_MONGODB_VERSION_DESC 1,16,0,0 -``` - -Commit and push this change: - -``` -$ git commit -m "Master is now X.Y-dev" phongo_version.h -$ git push mongodb -``` - -#### After releasing a patch version - -If this was a patch release, the maintenance branch must be merged up to master: - -``` -$ git checkout master -$ git pull mongodb master -$ git merge vX.Y --strategy=ours -$ git push mongodb -``` - -The `--strategy=ours` option ensures that all changes from the merged commits -will be ignored. This is OK because we previously ensured that the `master` -branch was up-to-date with all code changes in this maintenance branch before -tagging. - -### Publish release notes - -The following template should be used for creating GitHub release notes via -[this form](https://github.com/mongodb/mongo-php-driver/releases/new). The PECL -package may also be attached to the release notes. - -```markdown -The PHP team is happy to announce that version X.Y.Z of the [mongodb](https://pecl.php.net/package/mongodb) PHP extension is now available on PECL. - -**Release Highlights** - - - -A complete list of resolved issues in this release may be found in [JIRA]($JIRA_URL). - -**Documentation** - -Documentation is available on [PHP.net](https://php.net/set.mongodb). - -**Installation** - -You can either download and install the source manually, or you can install the extension with: - - pecl install mongodb-X.Y.Z - -or update with: - - pecl upgrade mongodb-X.Y.Z - -Windows binaries are attached to the GitHub release notes. -``` - -> **Note:** If this is an alpha or beta release, the installation examples -> should refer to the exact version (e.g. "mongodb-1.8.0beta2"). This is necessary -> because PECL prioritizes recent, stable releases over any stability preferences -> (e.g. "mongodb-beta"). - -The URL for the list of resolved JIRA issues will need to be updated with each -release. You may obtain the list from -[this form](https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=12484). - -If commits from community contributors were included in this release, append the -following section: - -```markdown -**Thanks** - -Thanks for our community contributors for X.Y.Z: - - * [$CONTRIBUTOR_NAME](https://github.com/$GITHUB_USERNAME) -``` - -Significant release announcements should also be posted in the -[MongoDB Product & Driver Announcements: Driver Releases](https://www.mongodb.com/community/forums/tags/c/announcements/driver-releases/110/php) forum. - -### Update compatibility tables in MongoDB docs - -For minor releases, create a DOCSP ticket indicating whether there are changes to MongoDB Server or PHP version -compatibility. The [compatibility tables](https://docs.mongodb.com/drivers/driver-compatibility-reference#php-driver-compatibility) -in the MongoDB documentation must be updated to account for new releases. Make sure to update both MongoDB and Language -compatibility tables, as shown in [this pull request](https://github.com/mongodb/docs-ecosystem/pull/642). diff --git a/Makefile.frag b/Makefile.frag index 4800ffe6b..9b181b4a0 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -20,6 +20,8 @@ help: @echo "" @echo -e "\t$$ make package.xml" @echo -e "\t - Creates a package.xml file with empty release notes" + @echo -e "\t$$ make package.xml RELEASE_NOTES_FILE=changelog" + @echo -e "\t - Creates a package.xml file with release notes read from the indicated file" @echo -e "\t$$ make package" @echo -e "\t - Creates the pecl archive to use for provisioning" @@ -59,7 +61,7 @@ package: pecl package package.xml package.xml: - php bin/prep-release.php $(MONGODB_VERSION) $(MONGODB_STABILITY) + php bin/prep-release.php $(MONGODB_VERSION) $(MONGODB_STABILITY) $(RELEASE_NOTES_FILE) libmongoc-version-current: cd src/libmongoc/ && python build/calc_release_version.py > ../LIBMONGOC_VERSION_CURRENT diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 000000000..14db48599 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,254 @@ +# Releasing + +## Branch management + +When releasing a new minor version of the driver (i.e. `X.Y.0`), create a new +maintenance branch named `vX.Y` from the default branch. Then, update the +version information in the default branch to the next minor release: + +```shell +$ ./bin/update-release-version.php to-next-minor-dev +``` + +Commit and push the resulting changes: + +```shell +$ git commit -m "Master is now X.Y-dev" phongo_version.h +$ git push mongodb +``` + +Before starting the release process, make sure that all open merge-up pull +requests containing changes from the release branch have been merged. Handling +the merge conflicts resulting from the version updates will be much more +difficult if other changes need merging. + +## Transition JIRA issues and version + +All issues associated with the release version should be in the "Closed" state +and have a resolution of "Fixed". Issues with other resolutions (e.g. +"Duplicate", "Works as Designed") should be removed from the release version so +that they do not appear in the release notes. + +Check the corresponding ".x" fix version to see if it contains any issues that +are resolved as "Fixed" and should be included in this release version. + +Update the version's release date and status from the +[Manage Versions](https://jira.mongodb.org/plugins/servlet/project-config/PHPC/versions) +page. + +## Trigger the release workflow + +Releases are done automatically through a GitHub Action. Visit the corresponding +[Release New Version](https://github.com/mongodb/mongo-php-driver/actions/workflows/release.yml) +workflow page to trigger a new build. Select the correct branch (e.g. `v1.18`) +and trigger a new run using the "Run workflow" button. In the following prompt, +enter the version number and the corresponding JIRA version ID for the release. +This version ID can be obtained from a link in the "Version" column on the +[PHPC releases page](https://jira.mongodb.org/projects/PHPC?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased). + +The automation will then create and push the necessary commits and tag, create a +draft release, and trigger the packaging builds for the newly created tag. The +release is created in a draft state and can be published once the release notes +have been updated. + +Alternatively, you may follow the [manual release process](#manual-release-process) +before continuing with the next section. + +## Upload package to PECL + +Once the packaging workflow has finished creating the PECL package, it will be +published as a build artifact of the package workflow, as well as a release +asset in the draft release. This package may be published via the +[Release Upload](https://pecl.php.net/release-upload.php) form. You will have one chance to confirm the package +information after uploading. + +> [!NOTE] +> If downloading the package from the build artifacts, be aware that these are +> always provided as zip files. You'll have to unpack the tgz archive prior to +> uploading it to PECL. This is not the case when downloading the release asset. + +## Update compatibility tables in MongoDB docs + +For minor releases, create a DOCSP ticket indicating whether there are changes +to MongoDB Server or PHP version compatibility. The [compatibility tables](https://docs.mongodb.com/drivers/driver-compatibility-reference#php-driver-compatibility) +in the MongoDB documentation must be updated to account for new releases. Make +sure to update both MongoDB and Language compatibility tables, as shown in +[this pull request](https://github.com/mongodb/docs-ecosystem/pull/642). + +## Handle merge-up pull request + +After the release automation pushes changes to the stable branch the release was +created from, the merge automation will create a new pull request to merge these +changes into the next versioned branch. Since version changes always create a +conflict, follow the "Ignoring Changes" section in the pull request to resolve +the conflicts and merge the pull request once the build completes. + +## Announce release + +Significant release announcements should also be posted in the +[MongoDB Product & Driver Announcements: Driver Releases](https://www.mongodb.com/community/forums/tags/c/announcements/driver-releases/110/php) forum. + +## Manual release process + +The following steps outline the manual release process. These are preserved +for historical reasons and releases that are currently not supported by the +release automation (e.g. beta releases). These steps are meant to be run instead +of [triggering the release workflow](#trigger-the-release-workflow). The +instructions assume that the steps preceding the release workflow have been +completed successfully. + +The command examples below assume that the canonical "mongodb" repository has +the remote name "mongodb". You may need to adjust these commands if you've given +the remote another name (e.g. "upstream"). The "origin" remote name was not used +as it likely refers to your personal fork. + +It helps to keep your own fork in sync with the "mongodb" repository (i.e. any +branches and tags on the main repository should also exist in your fork). This +is left as an exercise to the reader. + +### Update version info + +The PHP driver uses [semantic versioning](http://semver.org/). Do not break +backwards compatibility in a non-major release or your users will kill you. + +Before proceeding, ensure that the `master` branch is up-to-date with all code +changes in this maintenance branch. This is important because we will later +merge the ensuing release commits up to master with `--strategy=ours`, which +will ignore changes from the merged commits. + +Update the version and stability constants in `phongo_version.h` for the stable +release: + +```shell +$ ./bin/update-release-version.php to-stable +``` + +The Makefile targets for creating the PECL package depend on these constants, so +you must rebuild the extension after updating `phongo_version.h`. + +> [!NOTE] +> If this is an alpha or beta release, the version string should include the +> X.Y.Z version followed by the stability and an increment. For instance, the +> first beta release in the 1.4.0 series would be "1.4.0beta1". Alpha and beta +> releases use "alpha" and "beta" stability strings, respectively. Release +> candidates (e.g. "1.4.0RC1") also use "beta" stability. See +> [Documenting release stability and API stability](https://pear.php.net/manual/en/guide.developers.package2.stability.php) +> for more information. For each change to the suffixes of +> `PHP_MONGODB_VERSION`, increment the last digit of +> `PHP_MONGODB_VERSION_DESC`. + +### Build PECL package + +Create the PECL package description file with `make package.xml`. This creates +a `package.xml` file from a template. Version, author, and file information will +be filled in, but release notes must be copied manually from JIRA. + +After copying release notes, use `make package` to create the package file (e.g. +`mongodb-X.Y.Z.tgz`) and ensure that it can be successfully installed: + +``` +$ pecl install -f mongodb-X.Y.Z.tgz +``` + +### Update version info + +Commit the modified `phongo_version.h` file and push this change: + +``` +$ git commit -m "Package X.Y.Z" phongo_version.h +$ git push mongodb +``` + +### Tag the release + +Create a tag for the release and push: + +``` +$ git tag -a -m "Release X.Y.Z" X.Y.Z +$ git push mongodb --tags +``` + +Pushing the new tag will start the packaging process which provides the PECL +and Windows packages that should be attached to the release. + +### Release PECL package + +The PECL package may be published via the +[Release Upload](https://pecl.php.net/release-upload.php) form. You will have +one chance to confirm the package information after uploading. + +### Update version info back to dev + +After tagging, the version and stability constants in `phongo_version.h` should +be updated back to development status: + +```shell +$ ./bin/update-release-version.php to-next-patch-dev +``` + +Commit and push this change: + +``` +$ git commit -m "Back to -dev" phongo_version.h +$ git push mongodb +``` + +> [!NOTE] +> If this is an alpha, beta, or RC release, the version string should increment +> the stability sequence instead of the patch version. For example, if the +> constants were originally "1.4.0-dev" and "devel" and then changed to +> "1.4.0beta1" and "beta" for the first beta release, this step would see them +> ultimately changed to "1.4.0beta2-dev" and "devel". + +### Publish release notes + +The following template should be used for creating GitHub release notes via +[this form](https://github.com/mongodb/mongo-php-driver/releases/new). The PECL +package may also be attached to the release notes. + +```markdown +The PHP team is happy to announce that version X.Y.Z of the [mongodb](https://pecl.php.net/package/mongodb) PHP extension is now available on PECL. + +**Release Highlights** + + + +A complete list of resolved issues in this release may be found in [JIRA]($JIRA_URL). + +**Documentation** + +Documentation is available on [PHP.net](https://php.net/set.mongodb). + +**Installation** + +You can either download and install the source manually, or you can install the extension with: + + pecl install mongodb-X.Y.Z + +or update with: + + pecl upgrade mongodb-X.Y.Z + +Windows binaries are attached to the GitHub release notes. +``` + +> [!NOTE] +> If this is an alpha or beta release, the installation examples should refer to +> the exact version (e.g. "mongodb-1.8.0beta2"). This is necessary because PECL +> prioritizes recent, stable releases over any stability preferences +> (e.g. "mongodb-beta"). + +The URL for the list of resolved JIRA issues will need to be updated with each +release. You may obtain the list from +[this form](https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=12484). + +If commits from community contributors were included in this release, append the +following section: + +```markdown +**Thanks** + +Thanks for our community contributors for X.Y.Z: + +* [$CONTRIBUTOR_NAME](https://github.com/$GITHUB_USERNAME) +``` diff --git a/bin/package.xml.in b/bin/package.xml.in index 11b00fed8..87afd2a01 100644 --- a/bin/package.xml.in +++ b/bin/package.xml.in @@ -50,7 +50,7 @@ necessary to build a fully-functional MongoDB driver. Apache License - +%RELEASE_NOTES% %RELEASE_FILES% diff --git a/bin/prep-release.php b/bin/prep-release.php index 3bbe2cd56..93df6724c 100644 --- a/bin/prep-release.php +++ b/bin/prep-release.php @@ -151,17 +151,18 @@ function usage() { global $argv; echo "Usage:\n\t"; - echo $argv[0], " \n"; + echo $argv[0], " []\n"; exit(1); } -if ($argc != 3) { +if ($argc != 3 && $argc != 4) { usage(); } $VERSION = $argv[1]; $STABILITY = $argv[2]; +$RELEASE_NOTES_FILE = $argv[3] ?? null; /* 0.x.y. are developmental releases and cannot be stable */ if ((int)$VERSION < 1) { @@ -190,6 +191,7 @@ function usage() { "%RELEASE_VERSION%" => $VERSION, "%RELEASE_STABILITY%" => $STABILITY, "%RELEASE_FILES%" => join("\n", $TREE), + "%RELEASE_NOTES%" => is_string($RELEASE_NOTES_FILE) && file_exists($RELEASE_NOTES_FILE) ? file_get_contents($RELEASE_NOTES_FILE) : '', ); $contents = str_replace(array_keys($REPLACE), array_values($REPLACE), $contents); diff --git a/bin/update-release-version.php b/bin/update-release-version.php new file mode 100755 index 000000000..f6d1adfba --- /dev/null +++ b/bin/update-release-version.php @@ -0,0 +1,173 @@ +#!/usr/bin/env php + + +Commands: + to-stable: Mark the current version as stable + to-next-patch-dev: Update to the next patch development version + to-next-minor-dev: Update to the next minor development version + get-version: Print the current version number + +EOT; + + exit(1); +} + +function read_release_version(string $filename): array +{ + if (! is_file($filename)) { + throw new Exception(sprintf('File not found: "%s"', $filename)); + } + + $contents = file_get_contents($filename); + + $versions = []; + + if (! preg_match('/^#define PHP_MONGODB_VERSION "(.*)"$/m', $contents, $matches)) { + throw new Exception('Could not match PHP_MONGODB_VERSION'); + } + $versions['version'] = $matches[1]; + + if (! preg_match('/^#define PHP_MONGODB_STABILITY "(.*)"$/m', $contents, $matches)) { + throw new Exception('Could not match PHP_MONGODB_STABILITY'); + } + $versions['stability'] = $matches[1]; + + if (! preg_match('/^#define PHP_MONGODB_VERSION_DESC (\d+),(\d+),(\d+),(\d+)$/m', $contents, $matches)) { + throw new Exception('Could not match PHP_MONGODB_VERSION_DESC'); + } + $versions['versionComponents'] = array_slice($matches, 1); + + return $versions; +} + +function write_release_version(string $filename, array $version): void +{ + if (! is_file($filename)) { + throw new Exception(sprintf('File not found: "%s"', $filename)); + } + + $contents = file_get_contents($filename); + + $patterns = [ + '/^#define PHP_MONGODB_VERSION "(.*)"$/m', + '/^#define PHP_MONGODB_STABILITY "(.*)"$/m', + '/^#define PHP_MONGODB_VERSION_DESC (\d+),(\d+),(\d+),(\d+)$/m', + ]; + + $replacements = [ + sprintf('#define PHP_MONGODB_VERSION "%s"', $version['version']), + sprintf('#define PHP_MONGODB_STABILITY "%s"', $version['stability']), + sprintf('#define PHP_MONGODB_VERSION_DESC %s,%s,%s,%s', ...$version['versionComponents']), + ]; + + $contents = preg_replace($patterns, $replacements, $contents, -1, $count); + if ($count !== 3) { + throw new Exception('Could not properly replace contents in file'); + } + + file_put_contents($filename, $contents); +} + +function get_version_string_from_components(array $versionComponents): string +{ + return implode('.', array_slice($versionComponents, 0, 3)); +} + +function get_stable_version(array $versions): array +{ + if (! preg_match('/^(\d+\.\d+\.\d+)/', $versions['version'], $matches)) { + throw new Exception(sprintf('Version "%s" is not in the expected format', $versions['version'])); + } + + $version = $matches[1]; + + $expectedVersionString = get_version_string_from_components($versions['versionComponents']); + + if ($expectedVersionString !== $version) { + throw new Exception(sprintf('Version "%s" does not match version from components ("%s")', $version, $expectedVersionString)); + } + + $newVersions = [ + 'version' => $version, + 'stability' => 'stable', + 'versionComponents' => $versions['versionComponents'], + ]; + + // Increase build number + $newVersions['versionComponents'][3]++; + + return $newVersions; +} + +function get_next_patch_version(array $versions): array +{ + $versionComponents = $versions['versionComponents']; + + // Increase patch version, set build number to 0 + $versionComponents[2] += 1; + $versionComponents[3] = 0; + + return [ + 'version' => get_version_string_from_components($versionComponents) . 'dev', + 'stability' => 'devel', + 'versionComponents' => $versionComponents, + ]; +} + +function get_next_minor_version(array $versions): array +{ + $versionComponents = $versions['versionComponents']; + + // Increase minor version, set patch and build number to 0 + $versionComponents[1] += 1; + $versionComponents[2] = 0; + $versionComponents[3] = 0; + + return [ + 'version' => get_version_string_from_components($versionComponents) . 'dev', + 'stability' => 'devel', + 'versionComponents' => $versionComponents, + ]; +} + +if ($argc !== 2) { + usage(); +} + +$currentVersion = read_release_version(VERSION_FILENAME); + +switch ($argv[1] ?? null) { + case 'get-version': + echo $currentVersion['version']; + exit(0); + + case 'to-stable': + $newVersion = get_stable_version($currentVersion); + break; + + case 'to-next-patch-dev': + $newVersion = get_next_patch_version($currentVersion); + break; + + case 'to-next-minor-dev': + $newVersion = get_next_minor_version($currentVersion); + break; + + default: + usage(); +} + +write_release_version(VERSION_FILENAME, $newVersion); + +printf("Updated version number in version file from %s to %s\n", $currentVersion['version'], $newVersion['version']); + diff --git a/phongo_version.h b/phongo_version.h index 277aec328..6f19ddc67 100644 --- a/phongo_version.h +++ b/phongo_version.h @@ -22,7 +22,7 @@ * publishing a release. */ /* clang-format off */ -#define PHP_MONGODB_VERSION "1.18.2-dev" +#define PHP_MONGODB_VERSION "1.18.2dev" #define PHP_MONGODB_STABILITY "devel" #define PHP_MONGODB_VERSION_DESC 1,18,2,0 /* clang-format on */