Skip to content

Commit a6e8195

Browse files
committed
Add signed UPM example package
0 parents  commit a6e8195

6 files changed

Lines changed: 166 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Sign and release
2+
3+
on:
4+
push:
5+
tags:
6+
- "*"
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
sign:
13+
name: Sign UPM package
14+
runs-on: ubuntu-latest
15+
env:
16+
UPM_SERVICE_ACCOUNT_KEY_ID: ${{ secrets.UPM_SERVICE_ACCOUNT_KEY_ID }}
17+
UPM_SERVICE_ACCOUNT_KEY_SECRET: ${{ secrets.UPM_SERVICE_ACCOUNT_KEY_SECRET }}
18+
UPM_ORG_ID: ${{ secrets.UPM_ORG_ID }}
19+
PACKAGE_NAME: com.example.signed-upm
20+
PACKAGE_VERSION: 1.0.0
21+
22+
steps:
23+
- name: Check out repository
24+
uses: actions/checkout@v4
25+
26+
- name: Install Unity UPM CLI
27+
run: |
28+
curl -fsSL https://cdn.packages.unity.com/upm-cli/install.sh -o install.sh
29+
bash install.sh
30+
echo "$HOME/.upm/bin" >> "$GITHUB_PATH"
31+
32+
- name: Verify Unity UPM CLI
33+
run: upm --help
34+
35+
- name: Sign package
36+
run: |
37+
upm pack ./package --organization-id "$UPM_ORG_ID" --destination ./dist
38+
39+
- name: Verify signed archive
40+
run: |
41+
shopt -s nullglob
42+
archives=(dist/*.tgz dist/*.tar.gz)
43+
if [ "${#archives[@]}" -ne 1 ]; then
44+
printf 'Expected exactly one package archive in dist, found %s\n' "${#archives[@]}" >&2
45+
exit 1
46+
fi
47+
48+
archive="${archives[0]}"
49+
expected="dist/${PACKAGE_NAME}-${PACKAGE_VERSION}.tgz"
50+
if [ "$archive" != "$expected" ]; then
51+
printf 'Expected archive %s, found %s\n' "$expected" "$archive" >&2
52+
exit 1
53+
fi
54+
55+
tar -tzf "$archive" | grep -qx 'package/package.json'
56+
actual="$(tar -xOzf "$archive" package/package.json | jq -r '.name + "@" + .version')"
57+
if [ "$actual" != "${PACKAGE_NAME}@${PACKAGE_VERSION}" ]; then
58+
printf 'Expected %s@%s, found %s\n' "$PACKAGE_NAME" "$PACKAGE_VERSION" "$actual" >&2
59+
exit 1
60+
fi
61+
62+
- name: Create GitHub Release
63+
uses: softprops/action-gh-release@v2
64+
with:
65+
files: dist/com.example.signed-upm-1.0.0.tgz

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist/
2+
install.sh

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 OpenUPM
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Signed UPM Example
2+
3+
This repository demonstrates a minimal Unity Package Manager package that is
4+
packed and signed in GitHub Actions, then published as a GitHub Release asset.
5+
It is intentionally small so package authors can copy the workflow into their
6+
own repositories without carrying unrelated project structure.
7+
8+
Unity 6.3 checks digital signatures on tarball packages. The `upm pack`
9+
command creates a `.tgz` archive from the package folder and signs it with a
10+
Unity organization through service account credentials. The signed tarball can
11+
then be distributed directly, uploaded to a release, or submitted to a registry
12+
workflow that consumes release assets.
13+
14+
## Package Layout
15+
16+
- `package/package.json` is the Unity package manifest.
17+
- `package/package.json.meta` is the Unity meta file for the manifest.
18+
- `.github/workflows/ci.yml` signs the package only when a tag is pushed.
19+
20+
The package has no runtime code. It exists only to demonstrate release
21+
automation for signed UPM tarballs.
22+
23+
## GitHub Secrets
24+
25+
Create a Unity service account with package signing permission for the
26+
organization that should sign the package. Add these GitHub Actions secrets to
27+
the repository:
28+
29+
- `UPM_SERVICE_ACCOUNT_KEY_ID`
30+
- `UPM_SERVICE_ACCOUNT_KEY_SECRET`
31+
- `UPM_ORG_ID`
32+
33+
For a single package, repository secrets are enough. If several repositories in
34+
the same GitHub organization sign packages for the same Unity organization,
35+
prefer GitHub organization secrets scoped to only the repositories that need
36+
them. That keeps credential rotation centralized while avoiding broad access.
37+
38+
## Release Flow
39+
40+
Update `package/package.json`, commit the change, then push a version tag:
41+
42+
```sh
43+
git tag 1.0.0
44+
git push origin main 1.0.0
45+
```
46+
47+
The workflow installs Unity UPM CLI, runs `upm pack ./package`, verifies that
48+
the archive contains `package/package.json` for `com.example.signed-upm@1.0.0`,
49+
and attaches the signed tarball to the matching GitHub Release.
50+
51+
## OpenUPM
52+
53+
To publish a signed GitHub Release asset through OpenUPM, submit the package
54+
metadata with `trackingMode: githubRelease` and set `githubReleaseAssetName` to
55+
the signed archive filename, for example:
56+
57+
```yaml
58+
trackingMode: githubRelease
59+
githubReleaseAssetName: com.example.signed-upm-1.0.0.tgz
60+
```
61+
62+
OpenUPM will download the public release asset instead of packing from the git
63+
checkout.

package/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "com.example.signed-upm",
3+
"version": "1.0.0",
4+
"displayName": "Signed UPM Example",
5+
"description": "Minimal Unity package demonstrating Unity UPM code signing with GitHub Releases and OpenUPM.",
6+
"unity": "6000.3",
7+
"author": {
8+
"name": "OpenUPM",
9+
"url": "https://openupm.com"
10+
},
11+
"license": "MIT"
12+
}

package/package.json.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)