Skip to content

Commit f962384

Browse files
author
omer-topal
authored
feat: auto release with permify tag (#10)
1 parent e6ae218 commit f962384

9 files changed

Lines changed: 281 additions & 7 deletions

File tree

.github/workflows/auto-release.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Auto Release
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
paths:
9+
- '.openapi-generator/**'
10+
- 'docs/**'
11+
- 'src/**'
12+
- 'test/**'
13+
- 'package.json'
14+
- 'README.md'
15+
16+
permissions:
17+
contents: write
18+
19+
jobs:
20+
release:
21+
name: Create SDK Release
22+
timeout-minutes: 10
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Harden Runner
27+
uses: step-security/harden-runner@df199fb7be9f65074067a9eb93f12bb4c5547cf2 # v2.13.3
28+
with:
29+
egress-policy: audit
30+
31+
- name: Checkout repository
32+
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
33+
with:
34+
fetch-depth: 0
35+
36+
- name: Create tag and release
37+
env:
38+
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
39+
run: |
40+
PACKAGE_VERSION="$(sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)".*/\1/p' package.json | head -n 1)"
41+
OPENAPI_VERSION="$(sed -n 's/.*"version":[[:space:]]*"\([^"]*\)".*/\1/p' generator/openapi.json | head -n 1)"
42+
OPENAPI_PACKAGE_VERSION="${OPENAPI_VERSION#v}"
43+
44+
if [ -z "${PACKAGE_VERSION}" ]; then
45+
echo "Package version is empty. Skipping release creation."
46+
exit 0
47+
fi
48+
49+
if [ -n "${OPENAPI_PACKAGE_VERSION}" ] && [ "${PACKAGE_VERSION}" != "${OPENAPI_PACKAGE_VERSION}" ]; then
50+
echo "Package version (${PACKAGE_VERSION}) does not match OpenAPI version (${OPENAPI_PACKAGE_VERSION}). Skipping release creation."
51+
exit 0
52+
fi
53+
54+
TAG_NAME="v${PACKAGE_VERSION}"
55+
56+
if git rev-parse -q --verify "refs/tags/${TAG_NAME}" >/dev/null; then
57+
echo "Tag ${TAG_NAME} already exists. Skipping release creation."
58+
exit 0
59+
fi
60+
61+
echo "Creating release ${TAG_NAME}"
62+
git config --global user.name "GitHub Actions Bot"
63+
git config --global user.email "<>"
64+
git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}"
65+
git push origin "${TAG_NAME}"
66+
67+
gh release create "${TAG_NAME}" \
68+
--repo "${GITHUB_REPOSITORY}" \
69+
--title "${TAG_NAME}" \
70+
--generate-notes

.github/workflows/generator.yml

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,23 @@ jobs:
3737
distribution: temurin
3838
java-version: 17
3939

40+
- name: Setup Node.js
41+
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
42+
with:
43+
node-version: 20
44+
4045
# Generate the SDK
4146
- name: Generate JavaScript SDK
4247
run: |
4348
chmod +x generator/generate-sdk.sh
4449
generator/generate-sdk.sh
4550
51+
- name: Install dependencies
52+
run: npm install --no-package-lock
53+
54+
- name: Run smoke tests
55+
run: npm test
56+
4657
# Commit changes and open PR if there are changes
4758
- name: Commit changes
4859
id: commitchanges
@@ -68,6 +79,17 @@ jobs:
6879
if [ -n "${PR_NUMBER}" ]; then
6980
gh pr edit "${PR_NUMBER}" --title "${PR_TITLE}" --body "${PR_BODY}"
7081
else
71-
gh pr create --base main --head "${BRANCH_NAME}" --title "${PR_TITLE}" --body "${PR_BODY}" --label dependencies --label automated
82+
CREATE_ARGS=(--base main --head "${BRANCH_NAME}" --title "${PR_TITLE}" --body "${PR_BODY}")
83+
LABELS="$(gh label list --json name --jq '.[].name' || true)"
84+
85+
if printf '%s\n' "${LABELS}" | grep -qx 'dependencies'; then
86+
CREATE_ARGS+=(--label dependencies)
87+
fi
88+
89+
if printf '%s\n' "${LABELS}" | grep -qx 'automated'; then
90+
CREATE_ARGS+=(--label automated)
91+
fi
92+
93+
gh pr create "${CREATE_ARGS[@]}"
7294
fi
7395
shell: bash

.github/workflows/npm-publish.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ jobs:
2929
registry-url: "https://registry.npmjs.org"
3030

3131
- name: Install dependencies
32-
run: npm install
32+
run: npm install --no-package-lock
3333

3434
- name: Build
3535
run: npm run build
3636

37+
- name: Run smoke tests
38+
run: npm test
39+
3740
- name: Write release version
3841
run: |
3942
VERSION=${GITHUB_REF_NAME#v}

docker-compose.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
permify:
3+
image: "ghcr.io/permify/permify:v1.6.9"
4+
ports:
5+
- "3476:3476"
6+
- "3478:3478"
7+
command: "serve"

generator/generate-sdk.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
66
PROJECT_ROOT="${SCRIPT_DIR}/.."
77
OPENAPI_FILE="${SCRIPT_DIR}/openapi.json"
88
GENERATOR_VERSION="7.13.0"
9-
PACKAGE_VERSION="$(sed -n 's/^[[:space:]]*"version":[[:space:]]*"\([^"]*\)".*/\1/p' "${PROJECT_ROOT}/package.json" | head -n 1)"
9+
OPENAPI_VERSION="$(sed -n 's/.*"version":[[:space:]]*"\([^"]*\)".*/\1/p' "${OPENAPI_FILE}" | head -n 1)"
10+
PACKAGE_VERSION="${OPENAPI_VERSION#v}"
1011

11-
if [[ -z "${PACKAGE_VERSION}" ]]; then
12-
echo "Could not determine package version from ${PROJECT_ROOT}/package.json" >&2
12+
if [[ -z "${OPENAPI_VERSION}" || -z "${PACKAGE_VERSION}" ]]; then
13+
echo "Could not determine package version from ${OPENAPI_FILE}" >&2
1314
exit 1
1415
fi
1516

integration/live.spec.js

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import assert from 'assert';
2+
import * as PermifyApi from '../src/index';
3+
4+
const PERMIFY_BASE_URL = process.env.PERMIFY_BASE_URL || 'http://127.0.0.1:3476';
5+
const TENANT_ID = 't1';
6+
const RUN_ID = Date.now().toString(36);
7+
8+
function createApis() {
9+
const apiClient = new PermifyApi.ApiClient(PERMIFY_BASE_URL);
10+
apiClient.timeout = 10000;
11+
12+
return {
13+
schema: new PermifyApi.SchemaApi(apiClient),
14+
data: new PermifyApi.DataApi(apiClient),
15+
permission: new PermifyApi.PermissionApi(apiClient),
16+
};
17+
}
18+
19+
describe('Permify live REST tests', function() {
20+
this.timeout(20000);
21+
22+
it('denies a permission check when no relationship exists', async function() {
23+
const apis = createApis();
24+
const documentId = `denieddoc${RUN_ID}`;
25+
const subjectId = `denieduser${RUN_ID}`;
26+
const schema = `
27+
entity user {}
28+
29+
entity document {
30+
relation viewer @user
31+
32+
action view = viewer
33+
}
34+
`;
35+
36+
const schemaWrite = await apis.schema.schemasWrite(TENANT_ID, {
37+
schema,
38+
});
39+
40+
const check = await apis.permission.permissionsCheck(TENANT_ID, {
41+
metadata: {
42+
snap_token: '',
43+
schema_version: schemaWrite.schema_version,
44+
depth: 20,
45+
},
46+
entity: {
47+
type: 'document',
48+
id: documentId,
49+
},
50+
permission: 'view',
51+
subject: {
52+
type: 'user',
53+
id: subjectId,
54+
},
55+
});
56+
57+
assert.strictEqual(check.can, 'CHECK_RESULT_DENIED');
58+
});
59+
60+
it('looks up entities a subject can view', async function() {
61+
const apis = createApis();
62+
const subjectId = `lookupuser${RUN_ID}`;
63+
const expectedEntityIds = [
64+
`lookupdoca${RUN_ID}`,
65+
`lookupdocb${RUN_ID}`,
66+
`lookupdocc${RUN_ID}`,
67+
];
68+
const schema = `
69+
entity user {}
70+
71+
entity document {
72+
relation viewer @user
73+
74+
action view = viewer
75+
}
76+
`;
77+
78+
const schemaWrite = await apis.schema.schemasWrite(TENANT_ID, {
79+
schema,
80+
});
81+
82+
const dataWrite = await apis.data.dataWrite(TENANT_ID, {
83+
metadata: {
84+
schema_version: schemaWrite.schema_version,
85+
},
86+
tuples: [
87+
{
88+
entity: {
89+
type: 'document',
90+
id: expectedEntityIds[0],
91+
},
92+
relation: 'viewer',
93+
subject: {
94+
type: 'user',
95+
id: subjectId,
96+
},
97+
},
98+
{
99+
entity: {
100+
type: 'document',
101+
id: expectedEntityIds[1],
102+
},
103+
relation: 'viewer',
104+
subject: {
105+
type: 'user',
106+
id: subjectId,
107+
},
108+
},
109+
{
110+
entity: {
111+
type: 'document',
112+
id: expectedEntityIds[2],
113+
},
114+
relation: 'viewer',
115+
subject: {
116+
type: 'user',
117+
id: subjectId,
118+
},
119+
},
120+
],
121+
});
122+
123+
const lookup = await apis.permission.permissionsLookupEntity(TENANT_ID, {
124+
metadata: {
125+
snap_token: dataWrite.snap_token,
126+
schema_version: schemaWrite.schema_version,
127+
depth: 20,
128+
},
129+
entity_type: 'document',
130+
permission: 'view',
131+
subject: {
132+
type: 'user',
133+
id: subjectId,
134+
},
135+
});
136+
137+
assert.deepStrictEqual(lookup.entity_ids.sort(), expectedEntityIds.sort());
138+
});
139+
});

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
"scripts": {
88
"build": "babel src -d dist",
99
"prepare": "npm run build",
10-
"test": "mocha --require @babel/register --recursive"
10+
"test": "mocha --require @babel/register --recursive",
11+
"test:live": "mocha --require @babel/register integration/**/*.spec.js",
12+
"run-live-tests": "./scripts/run-live-tests.sh",
13+
"run-instance": "./scripts/run-live-tests.sh"
1114
},
1215
"browser": {
1316
"fs": false

scripts/commit-changes.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -euo pipefail
44

55
branch_name="${1:?branch name is required}"
66

7-
if git diff --quiet; then
7+
if [[ -z "$(git status --porcelain)" ]]; then
88
echo "changes_made=0" >> "${GITHUB_OUTPUT}"
99
echo "No changes detected"
1010
exit 0

scripts/run-live-tests.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yaml"
7+
PERMIFY_BASE_URL="${PERMIFY_BASE_URL:-http://127.0.0.1:3476}"
8+
9+
cleanup() {
10+
docker compose -f "${COMPOSE_FILE}" down -v >/dev/null 2>&1 || true
11+
}
12+
13+
trap cleanup EXIT
14+
15+
cd "${ROOT_DIR}"
16+
17+
docker compose -f "${COMPOSE_FILE}" up -d
18+
19+
for attempt in {1..60}; do
20+
if curl -s -o /dev/null "${PERMIFY_BASE_URL}/healthz"; then
21+
npm run test:live
22+
exit 0
23+
fi
24+
25+
sleep 1
26+
done
27+
28+
echo "Permify did not become reachable at ${PERMIFY_BASE_URL} within 60 seconds." >&2
29+
exit 1

0 commit comments

Comments
 (0)