Skip to content
Open
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
schedule:
- cron: '0 1 1-31/2 * *'

permissions:
contents: read

jobs:

Expand Down
57 changes: 39 additions & 18 deletions .github/workflows/dockerhubpublish.yml
Original file line number Diff line number Diff line change
@@ -1,52 +1,73 @@
name: build&publishtoDockerHub

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+(.*)'
# Normally driven by graphistry/graphistry CI (.github/workflows/base.yml jobs
# push_gak_tag + trigger-gak-build): it tags this repo with the graphistry VERSION,
# then dispatches this workflow on master with cuda_versions '["13", "12"]' and
# polls the run (30 min budget) — so the workflow name and master ref must stay.
# Manual flow: tag on master, then dispatch from master; the image version comes
# from the latest tag (`git describe --tags`).
# (A tag-push trigger existed but its pattern never matched a real tag, and a tag
# path would let any tag creator reach the DockerHub token, so it was removed.)

on:
workflow_dispatch:
inputs:
version:
description: 'Version to bump to'
required: false
cuda_versions:
description: 'JSON array of CUDA versions'
description: 'JSON array of CUDA versions, matching graphistry-forge-base tag suffixes (e.g. "13", "12")'
required: false
default: '["12.8", "11.8"]'
default: '["13", "12"]'

workflow_call:

permissions: {}

jobs:
docker-build-publish:
# Pushes public images (including :latest-<cuda>), so only master may publish;
# dispatch from any other ref is skipped. The DockerHub token lives on the protected
# `dockerhub-publish` environment (master only + required reviewers; see DEVELOP.md).
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest-4-cores
environment: dockerhub-publish
permissions:
contents: read
strategy:
matrix:
CUDA_SHORT_VERSION: ${{ fromJSON(inputs.cuda_versions || '["12.8", "11.8"]') }}
CUDA_SHORT_VERSION: ${{ fromJSON(inputs.cuda_versions || '["13", "12"]') }}
fail-fast: true


steps:

- name: checkout repo
uses: actions/checkout@v3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- name: get most recent tag
run: |
echo "RELEASE_VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
echo "CUDA_SHORT_VERSION=${{ matrix.CUDA_SHORT_VERSION }}" >> $GITHUB_ENV
# Values flow into $GITHUB_ENV and image tags: reject anything but N or N.N
# (a newline in the free-form dispatch input would inject env vars).
if ! [[ "$MATRIX_CUDA_SHORT_VERSION" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
echo "::error::Invalid CUDA version in cuda_versions input (expected N or N.N, e.g. 13 or 12.8)"
exit 1
fi
echo "RELEASE_VERSION=$(git describe --tags --abbrev=0)" >> "$GITHUB_ENV"
echo "CUDA_SHORT_VERSION=${MATRIX_CUDA_SHORT_VERSION}" >> "$GITHUB_ENV"
env:
MATRIX_CUDA_SHORT_VERSION: ${{ matrix.CUDA_SHORT_VERSION }}

- name: check env
run: |
echo $RELEASE_VERSION
echo ${{ env.RELEASE_VERSION }}
echo $CUDA_SHORT_VERSION
echo ${{ env.CUDA_SHORT_VERSION }}
echo "$RELEASE_VERSION"
echo "$CUDA_SHORT_VERSION"

- name: Login to DockerHub
uses: docker/login-action@v2
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand All @@ -58,12 +79,12 @@ jobs:

run: |
cd src/docker \
&& GRAPHISTRY_FORGE_BASE_VERSION=v${{ env.RELEASE_VERSION }}-${{ env.CUDA_SHORT_VERSION }} docker compose -f docker-compose.yml build
&& GRAPHISTRY_FORGE_BASE_VERSION="v${RELEASE_VERSION}-${CUDA_SHORT_VERSION}" docker compose -f docker-compose.yml build

- name: tag the image
run: |
docker tag graphistry/graph-app-kit-st:latest-${{ env.CUDA_SHORT_VERSION }} graphistry/graph-app-kit-st:v${{ env.RELEASE_VERSION }}-${{ env.CUDA_SHORT_VERSION }}
docker tag "graphistry/graph-app-kit-st:latest-${CUDA_SHORT_VERSION}" "graphistry/graph-app-kit-st:v${RELEASE_VERSION}-${CUDA_SHORT_VERSION}"

- name: Publish Graph-App-Kit to DockerHub
run: |
docker push graphistry/graph-app-kit-st:v${{ env.RELEASE_VERSION }}-${{ env.CUDA_SHORT_VERSION }} && docker push graphistry/graph-app-kit-st:latest-${{ env.CUDA_SHORT_VERSION }}
docker push "graphistry/graph-app-kit-st:v${RELEASE_VERSION}-${CUDA_SHORT_VERSION}" && docker push "graphistry/graph-app-kit-st:latest-${CUDA_SHORT_VERSION}"
81 changes: 51 additions & 30 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,75 @@
name: Publish

# Uploads the CloudFormation templates that customers deploy (README "Launch Stack")
# to the public bucket under templates/latest/.
#
# Only master may publish, and only through the protected `publish-templates`
# environment (required reviewers + deployment branch policy: master). AWS access
# is a short-lived GitHub OIDC session whose IAM role trusts only that environment
# and may only write templates/latest/*. Setup: DEVELOP.md "AWS Publish action".

on:

#Merge
push:
branches:
- master
paths:
- 'src/bootstraps/core/*.yml'
- 'src/bootstraps/neptune/*.yml'
- '.github/workflows/publish.yml'

#Label
pull_request:
types: [labeled]


#Enable UI-driven branch testing
#Manual republish (master only; other refs are skipped)
workflow_dispatch:

#Test main bidaily @ 1a
schedule:
- cron: '0 1 1-31/2 * *'
permissions: {}

jobs:

stub_mt:
name: Always-succeed step to prevent appearing as a failure
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Do nothing
run: echo "Do nothing"

publish:
name: Upload to Amazon S3
if: github.event.action != 'labeled' || github.event.label.name == 'publish'
name: Upload CloudFormation templates to S3
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
timeout-minutes: 15
# Job-level and keyed by ref so a skipped non-master dispatch never joins
# (and cancels a pending run in) the master publish queue.
concurrency:
group: publish-templates-${{ github.ref }}
cancel-in-progress: false
environment:
name: publish-templates
url: https://graph-app-kit-repo-public.s3.us-east-2.amazonaws.com/templates/latest/core/graphistry.yml
permissions:
contents: read
id-token: write
env:
AWS_REGION: us-east-2
S3_BUCKET: graph-app-kit-repo-public
AWS_ROLE_ARN: ${{ vars.AWS_S3_PUBLISH_ROLE_ARN }}

steps:
- name: Require OIDC role configuration
run: |
if [ -z "$AWS_ROLE_ARN" ]; then
echo "::error::Environment variable AWS_S3_PUBLISH_ROLE_ARN is not set on the publish-templates environment"
exit 1
fi

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@e1253824e5c10ff9df46874f81ed3ec929e19cfd # v6.3.0
with:
aws-access-key-id: ${{ secrets.S3_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.S3_AWS_REGION_PUBLIC }}
role-to-assume: ${{ env.AWS_ROLE_ARN }}
role-session-name: graph-app-kit-publish-${{ github.run_id }}
aws-region: ${{ env.AWS_REGION }}

- name: Copy CloudFormation templates
run: |
aws s3 cp src/bootstraps/core/graphistry.yml "s3://${{ secrets.AWS_S3_BUCKET_PUBLIC}}/templates/latest/core/graphistry.yml"
aws s3 cp src/bootstraps/core/minimal.yml "s3://${{ secrets.AWS_S3_BUCKET_PUBLIC}}/templates/latest/core/minimal.yml"
aws s3 cp src/bootstraps/neptune/graphistry.yml "s3://${{ secrets.AWS_S3_BUCKET_PUBLIC}}/templates/latest/neptune/graphistry.yml"
aws s3 cp src/bootstraps/neptune/minimal.yml "s3://${{ secrets.AWS_S3_BUCKET_PUBLIC}}/templates/latest/neptune/minimal.yml"

set -euo pipefail
for template in core/graphistry.yml core/minimal.yml neptune/graphistry.yml neptune/minimal.yml; do
aws s3 cp "src/bootstraps/${template}" "s3://${S3_BUCKET}/templates/latest/${template}"
done
11 changes: 11 additions & 0 deletions .github/workflows/scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ on:
schedule:
- cron: '0 4 * * *'

permissions:
contents: read

jobs:

cancel_outstanding:
name: Detect and cancel outstanding runs of this workflow
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-security-scan') }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
actions: write
steps:
- name: Cancel Previous Runs
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-cancel') }}
Expand All @@ -26,6 +31,9 @@ jobs:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-security-scan') }}
runs-on: ubuntu-latest-4-cores
timeout-minutes: 30
permissions:
contents: read
security-events: write
env:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
Expand Down Expand Up @@ -89,6 +97,9 @@ jobs:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-security-scan') }}
runs-on: ubuntu-latest-4-cores
timeout-minutes: 30
permissions:
contents: read
security-events: write
env:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ Extensions:

See [projects page](https://github.com/graphistry/graph-app-kit/projects) and [open pull requests](https://github.com/graphistry/graph-app-kit/pulls)

### Security

* Publish workflow: CloudFormation templates (public S3 `templates/latest/`) publish only from `master`, via the `publish-templates` environment (required reviewers) and a GitHub OIDC role scoped to `templates/latest/*`; the PR `publish` label and schedule no longer publish
* DockerHub workflow: publish only by dispatch from `master`, via the `dockerhub-publish` environment; drop the tag-push trigger (its pattern never matched); validate `cuda_versions` entries (`N` or `N.N`) and default them to `["13", "12"]` to match what graphistry CI dispatches and the current `graphistry-forge-base` tags
* Requires one-time repo/AWS setup before merge, plus post-merge cleanup (retire the old AWS key and DockerHub token, set the default token to read-only): see `DEVELOP.md` "One-time setup"

### Infra

* Publish workflows: `permissions: {}` with per-job grants, actions pinned to commit SHAs (`actions/checkout` v7.0.1, `aws-actions/configure-aws-credentials` v6.3.0, `docker/login-action` v4.6.0), `persist-credentials: false`, no `${{ }}` interpolation in `run:` scripts
* Template publish runs only when templates or the workflow change on `master` (or on manual dispatch)
* CI and Scan workflows declare explicit least-privilege `permissions:` so the repo default token can be set to read-only

### Dev

* Add agent skills under `.agents/skills/`: `plan` (file-based task plans) and `review` (multi-wave PR review), adapted for this repo's Python views, GitHub Actions publish workflows, and CloudFormation templates. Add `AGENTS.md`; gitignore `plans/`
Expand Down
Loading
Loading