Skip to content
This repository was archived by the owner on Aug 26, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/lint.yml → .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: Lint policies

on:
push:
workflow_dispatch:

jobs:
lint:
name: Lint policies
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

Expand All @@ -27,3 +28,19 @@ jobs:
- name: Regal Lint
if: ${{ !cancelled() }}
run: regal lint --format github .

deploy:
name: Deploy policies
runs-on: ubuntu-latest
permissions:
contents: read
needs: lint
if: success() && github.ref == 'refs/heads/main'

steps:
- uses: actions/checkout@v4

- name: Upload
env:
PHYLUM_TOKEN: ${{ secrets.PHYLUM_POLICY_TOKEN }}
run: python3 .github/workflows/upload.py
74 changes: 74 additions & 0 deletions .github/workflows/upload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Script to upload a set of policy files to Phylum.
"""

import contextlib
import io
import json
import os
from pathlib import Path
import shutil
from urllib.error import HTTPError
from urllib.parse import quote
from urllib.request import Request, urlopen
import uuid
import sys

# Set the group name if you are uploading policies for a group.
GROUP_NAME = None
token = os.environ["PHYLUM_TOKEN"]
version = os.environ.get("GITHUB_SHA", None)
BASE_ADDRESS = "https://api.phylum.io/api/"

# Build a multipart form body.
boundary = uuid.uuid4().hex
body = io.BytesIO()

for file in Path.cwd().glob("*.rego"):
body.write(f"--{boundary}\r\n".encode("ascii"))
body.write(
f'Content-Disposition: form-data; name="{file.stem}"; filename="{file.name}"\r\n'.encode(
"ascii"
)
)
body.write(b"Content-Type: text/plain\r\n\r\n")

with file.open("rb") as f:
shutil.copyfileobj(f, body)

body.write(b"\r\n")

body.write(f"--{boundary}--".encode("ascii"))

# Send the request.
if GROUP_NAME is None:
endpoint = f"{BASE_ADDRESS}v0/available-policies"
else:
endpoint = (
f"{BASE_ADDRESS}v0/groups/{quote(GROUP_NAME, safe='')}/available-policies"
)

if version is not None:
endpoint = f"{endpoint}?version={quote(version, safe='')}"

request = Request(
endpoint,
data=body.getbuffer(),
headers={
"Authorization": f"Bearer {token}",
"Content-Type": f'multipart/form-data;boundary="{boundary}"',
},
method="PUT",
)

try:
with urlopen(request) as f:
pass
except HTTPError as error:
response = error.read().decode("utf8", errors="replace")
with contextlib.suppress(json.JSONDecodeError):
# Phylum's API returns JSON error descriptions.
# If that's what we got, reformat it to be more readable.
response = json.dumps(json.loads(response), indent=2)
print(response)
sys.exit(1)