Skip to content

Commit df3e69d

Browse files
authored
PHPC-1584: Sign releases (#1544)
* Create signed git artifacts upon release * Generate signature for PECL package * Fix writing release message to file * Remove unnecessary pip install * Change image variable usage * Sign Windows DLLs * Move composite actions to separate directory * Extract signing functionality to composite actions * Add release integrity information * Use garasign actions from drivers-github-tools * Add comment explaining cross-os cache * Remove submodule install for Windows signing job * Fix name and contents of Windows build artifacts" * Don't hardcode tag message file name * Restore original tag message * Add newline to tag message
1 parent 26d2f52 commit df3e69d

File tree

9 files changed

+184
-30
lines changed

9 files changed

+184
-30
lines changed

.github/workflows/windows/build/action.yml renamed to .github/actions/windows/build/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ runs:
1919
steps:
2020
- name: Prepare build environment
2121
id: prepare-build-env
22-
uses: ./.github/workflows/windows/prepare-build
22+
uses: ./.github/actions/windows/prepare-build
2323
with:
2424
version: ${{ inputs.version }}
2525
arch: ${{ inputs.arch }}

.github/workflows/commit-and-tag.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
PACKAGE_VERSION=$1
5+
GPG_KEY_ID=$2
6+
TAG_MESSAGE_FILE=$3
7+
8+
gpgloader
9+
10+
# Create signed "Package x.y.z" commit
11+
echo "Create package commit"
12+
git commit -m "Package ${PACKAGE_VERSION}" -s --gpg-sign=${GPG_KEY_ID} phongo_version.h
13+
14+
# Create signed "Release x.y.z" tag
15+
echo "Create release tag"
16+
git tag -F ${TAG_MESSAGE_FILE} -s --local-user=${GPG_KEY_ID} ${PACKAGE_VERSION}

.github/workflows/package-release.yml

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
submodules: true
2222

2323
- name: "Build Driver"
24-
uses: ./.github/workflows/linux/build
24+
uses: ./.github/actions/linux/build
2525
with:
2626
version: "8.3"
2727

@@ -38,27 +38,43 @@ jobs:
3838
# PECL always uses the version for the package name.
3939
# Read it from the version file and store in env to use when uploading artifacts
4040
- name: "Read current package version"
41-
run: echo "PACKAGE_VERSION=$(./bin/update-release-version.php get-version)" >> "$GITHUB_ENV"
41+
run: |
42+
PACKAGE_VERSION=$(./bin/update-release-version.php get-version)
43+
echo "PACKAGE_VERSION=${PACKAGE_VERSION}" >> "$GITHUB_ENV"
44+
echo "PACKAGE_FILE=mongodb-${PACKAGE_VERSION}.tgz" >> "$GITHUB_ENV"
45+
46+
- name: "Create detached signature for PECL package"
47+
uses: mongodb-labs/drivers-github-tools/garasign/gpg-sign@main
48+
with:
49+
filenames: ${{ env.PACKAGE_FILE }}
50+
garasign_username: ${{ secrets.GRS_CONFIG_USER1_USERNAME }}
51+
garasign_password: ${{ secrets.GRS_CONFIG_USER1_PASSWORD }}
52+
artifactory_username: ${{ secrets.ARTIFACTORY_USER }}
53+
artifactory_password: ${{ secrets.ARTIFACTORY_PASSWORD }}
4254

4355
- name: "Install release archive to verify correctness"
44-
run: sudo pecl install mongodb-${{ env.PACKAGE_VERSION }}.tgz
56+
run: sudo pecl install ${{ env.PACKAGE_FILE }}
4557

46-
- name: "Upload artifact"
58+
- name: "Upload artifacts"
4759
uses: actions/upload-artifact@v4
4860
with:
49-
name: mongodb-${{ env.PACKAGE_VERSION }}.tgz
50-
path: mongodb-${{ env.PACKAGE_VERSION }}.tgz
61+
name: ${{ env.PACKAGE_FILE }}
62+
path: |
63+
${{ env.PACKAGE_FILE }}
64+
${{ env.PACKAGE_FILE }}.sig
5165
retention-days: 3
5266

53-
- name: "Upload release artifact"
54-
run: gh release upload ${{ github.ref_name }} mongodb-${{ env.PACKAGE_VERSION }}.tgz
67+
- name: "Upload release artifacts"
68+
run: gh release upload ${{ github.ref_name }} ${{ env.PACKAGE_FILE }} ${{ env.PACKAGE_FILE }}.sig
5569
continue-on-error: true
5670
env:
5771
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5872

5973
build-windows:
6074
name: "Create Windows package"
61-
runs-on: windows-2022
75+
# windows-latest is required to use enableCrossOsArchive with Ubuntu in the
76+
# next step. See https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cross-os-cache
77+
runs-on: windows-latest
6278
defaults:
6379
run:
6480
shell: cmd
@@ -78,7 +94,7 @@ jobs:
7894

7995
- name: "Build Driver"
8096
id: build-driver
81-
uses: ./.github/workflows/windows/build
97+
uses: ./.github/actions/windows/build
8298
with:
8399
version: ${{ matrix.php }}
84100
arch: ${{ matrix.arch }}
@@ -91,20 +107,73 @@ jobs:
91107
env:
92108
BUILD_DIR: ${{ steps.build-driver.outputs.build-dir }}
93109

110+
- name: "Cache build artifacts for subsequent builds"
111+
uses: actions/cache/save@v4
112+
with:
113+
key: ${{ github.sha }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}
114+
enableCrossOsArchive: true
115+
path: |
116+
php_mongodb.dll
117+
php_mongodb.pdb
118+
119+
sign-and-publish-windows:
120+
name: "Sign and Publish Windows package"
121+
needs: [build-windows]
122+
# ubuntu-latest is required to use enableCrossOsArchive
123+
# See https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cross-os-cache
124+
runs-on: "ubuntu-latest"
125+
126+
strategy:
127+
fail-fast: false
128+
matrix:
129+
# Note: keep this in sync with the Windows matrix in windows-tests.yml
130+
php: [ "7.4", "8.0", "8.1", "8.2", "8.3" ]
131+
arch: [ x64, x86 ]
132+
ts: [ ts, nts ]
133+
134+
steps:
135+
- uses: actions/checkout@v4
136+
137+
- name: Restore cached build artifacts
138+
id: cache-build-artifacts
139+
uses: actions/cache/restore@v4
140+
with:
141+
fail-on-cache-miss: true
142+
key: ${{ github.sha }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}
143+
enableCrossOsArchive: true
144+
path: |
145+
php_mongodb.dll
146+
php_mongodb.pdb
147+
148+
- name: "Create detached DLL signature"
149+
uses: mongodb-labs/drivers-github-tools/garasign/gpg-sign@main
150+
with:
151+
filenames: php_mongodb.dll
152+
garasign_username: ${{ secrets.GRS_CONFIG_USER1_USERNAME }}
153+
garasign_password: ${{ secrets.GRS_CONFIG_USER1_PASSWORD }}
154+
artifactory_username: ${{ secrets.ARTIFACTORY_USER }}
155+
artifactory_password: ${{ secrets.ARTIFACTORY_PASSWORD }}
156+
94157
- name: "Upload DLL and PDB files as build artifacts"
95158
uses: actions/upload-artifact@v4
96159
with:
97160
name: php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}
98161
path: |
99162
php_mongodb.dll
163+
php_mongodb.dll.sig
100164
php_mongodb.pdb
165+
CREDITS
166+
CONTRIBUTING.md
167+
LICENSE
168+
README.md
169+
THIRD_PARTY_NOTICES
101170
retention-days: 3
102171

103172
- name: "Create and upload release artifact"
104173
run: |
105-
set ARCHIVE=php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}.zip
106-
zip %ARCHIVE% php_mongodb.dll php_mongodb.pdb CREDITS CONTRIBUTING.md LICENSE README.md THIRD_PARTY_NOTICES
107-
gh release upload ${{ github.ref_name }} %ARCHIVE%
174+
ARCHIVE=php_mongodb-${{ github.ref_name }}-${{ matrix.php }}-${{ matrix.ts }}-${{ matrix.arch }}.zip
175+
zip ${ARCHIVE} php_mongodb.dll php_mongodb.dll.sig php_mongodb.pdb CREDITS CONTRIBUTING.md LICENSE README.md THIRD_PARTY_NOTICES
176+
gh release upload ${{ github.ref_name }} ${ARCHIVE}
108177
continue-on-error: true
109178
env:
110179
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,6 @@ jobs:
8989
git config user.name "${GIT_AUTHOR_NAME}"
9090
git config user.email "${GIT_AUTHOR_EMAIL}"
9191
92-
# Create the "Package x.y.z" commit that will be the base of our tag
93-
- name: "Create release commit"
94-
run: git commit -m "Package ${{ env.PACKAGE_VERSION }}" phongo_version.h
95-
9692
# Create a draft release with a changelog
9793
# TODO: Consider using the API to generate changelog
9894
- name: "Create draft release with generated changelog"
@@ -101,14 +97,39 @@ jobs:
10197
- name: "Read changelog from draft release"
10298
run: gh release view ${{ env.PACKAGE_VERSION }} --json body --template '{{ .body }}' >> changelog
10399

104-
# TODO: Sign tag
105-
- name: "Create release tag"
106-
run: git tag -a -F changelog ${{ env.PACKAGE_VERSION }}
107-
108-
- name: "Update version information to next patch development release"
100+
- name: "Prepare tag message"
109101
run: |
110-
./bin/update-release-version.php to-next-patch-dev
111-
git commit -m "Back to -dev" phongo_version.h
102+
echo -e "Release ${PACKAGE_VERSION}\n" > tag-message
103+
cat changelog >> tag-message
104+
105+
# This step creates the "Package x.y.z" commit that will be the base of
106+
# our tag and creates the release tag. This is run inside the container in
107+
# order to create signed git artifacts
108+
- name: "Create package commit and release tag"
109+
uses: mongodb-labs/drivers-github-tools/garasign/git-sign@main
110+
with:
111+
command: "$(pwd)/.github/workflows/commit-and-tag.sh ${{ env.PACKAGE_VERSION }} ${{ vars.GPG_KEY_ID }} tag-message"
112+
garasign_username: ${{ secrets.GRS_CONFIG_USER1_USERNAME }}
113+
garasign_password: ${{ secrets.GRS_CONFIG_USER1_PASSWORD }}
114+
artifactory_username: ${{ secrets.ARTIFACTORY_USER }}
115+
artifactory_password: ${{ secrets.ARTIFACTORY_PASSWORD }}
116+
117+
# This step needs to happen outside of the container, as PHP is not
118+
# available within.
119+
- name: "Bump to next development release"
120+
run: ./bin/update-release-version.php to-next-patch-dev
121+
122+
# Create a signed "back to -dev" commit, again inside the container
123+
- name: "Create dev commit"
124+
uses: mongodb-labs/drivers-github-tools/garasign/git-sign@main
125+
with:
126+
# Setup can be skipped as it was already done before
127+
skip_setup: true
128+
command: "git commit -m 'Back to -dev' -s --gpg-sign=${{ vars.GPG_KEY_ID }} phongo_version.h"
129+
garasign_username: ${{ secrets.GRS_CONFIG_USER1_USERNAME }}
130+
garasign_password: ${{ secrets.GRS_CONFIG_USER1_PASSWORD }}
131+
artifactory_username: ${{ secrets.ARTIFACTORY_USER }}
132+
artifactory_password: ${{ secrets.ARTIFACTORY_PASSWORD }}
112133

113134
# TODO: Manually merge using ours strategy. This avoids merge-up pull requests being created
114135
# Process is:
@@ -122,7 +143,9 @@ jobs:
122143

123144
- name: "Prepare release message"
124145
run: |
125-
echo "${{ format(env.default-release-message, env.PACKAGE_VERSION, inputs.jira-version-number) }}" > release-message
146+
cat > release-message <<'EOL'
147+
${{ format(env.default-release-message, env.PACKAGE_VERSION, inputs.jira-version-number) }}
148+
EOL
126149
cat changelog >> release-message
127150
128151
# Update release with correct release information

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464

6565
- name: "Build Driver"
6666
id: build-driver
67-
uses: ./.github/workflows/linux/build
67+
uses: ./.github/actions/linux/build
6868
with:
6969
version: ${{ matrix.php-version }}
7070

.github/workflows/windows-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535

3636
- name: "Build Driver"
3737
id: build-driver
38-
uses: ./.github/workflows/windows/build
38+
uses: ./.github/actions/windows/build
3939
with:
4040
version: ${{ matrix.php }}
4141
arch: ${{ matrix.arch }}
@@ -74,7 +74,7 @@ jobs:
7474

7575
- name: Prepare build environment
7676
id: prepare-build
77-
uses: ./.github/workflows/windows/prepare-build
77+
uses: ./.github/actions/windows/prepare-build
7878
with:
7979
version: ${{ matrix.php }}
8080
arch: ${{ matrix.arch }}

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,53 @@ This extension is intended to be used alongside the
3636
[MongoDB PHP Library](https://github.com/mongodb/mongo-php-library), which is
3737
distributed as the
3838
[`mongodb/mongodb`](https://packagist.org/packages/mongodb/mongodb) package for
39-
for [Composer](https://getcomposer.org).
39+
[Composer](https://getcomposer.org).
40+
41+
## Release Integrity
42+
43+
Releases are created automatically and signed using the
44+
[PHP team's GPG key](https://pgp.mongodb.com/php-driver.asc). This applies to
45+
the git tag as well as all release packages provided as part of a
46+
[GitHub release](https://github.com/mongodb/mongo-php-library/releases). To
47+
verify the provided packages, download the key and import it using `gpg`:
48+
49+
```shell
50+
gpg --import php-driver.asc
51+
```
52+
53+
### PECL package
54+
55+
PECL packages are made available as release artifacts on GitHub, as well as on
56+
the [PECL homepage](https://pecl.php.net/mongodb). The GitHub release will also
57+
contain a detached signature file for the PECL package (named
58+
`mongodb-X.Y.Z.tgz.sig`).
59+
60+
To verify the integrity of the downloaded package, run the following command:
61+
62+
```shell
63+
gpg --verify mongodb-X.Y.Z.tgz.sig mongodb-X.Y.Z.tgz
64+
```
65+
66+
> [!NOTE]
67+
> No verification is done when using `pecl` to install the package. To ensure
68+
> release integrity when using `pecl`, download the tarball manually from the
69+
> GitHub release, verify the signature, then install the package from the
70+
> downloaded tarball using `pecl install mongodb-X.Y.Z.tgz`.
71+
72+
### Windows
73+
74+
Windows binaries distributed through GitHub releases contain a detached
75+
signature for the `php_mongodb.dll` file named `php_mongodb.dll.sig`. To verify
76+
the integrity of the DLL, run the following command:
77+
78+
```shell
79+
gpg --verify php_mongodb.dll.sig php_mongodb.dll.tgz
80+
```
81+
82+
> [!NOTE]
83+
> Windows binaries distributed directly through PECL are not signed by MongoDB
84+
> and cannot be verified. If you need to verify the integrity of the downloaded
85+
> binary, always download them from the GitHub release.
4086
4187
## Reporting Issues
4288

0 commit comments

Comments
 (0)