Skip to content

CI: redeploy ok-dspace on pushes to clarin-v7 - #1393

Merged
kosarko merged 4 commits into
clarin-v7from
cicd/dispatch-ok-dspace
Jul 23, 2026
Merged

CI: redeploy ok-dspace on pushes to clarin-v7#1393
kosarko merged 4 commits into
clarin-v7from
cicd/dispatch-ok-dspace

Conversation

@kosarko

@kosarko kosarko commented Jul 22, 2026

Copy link
Copy Markdown
Member

Appends a deploy-ok-dspace job to docker.yml that notifies
ufal/dspace-k8s once the images this test environment
consumes have been pushed. Target environment: https://ok-dspace.dyn.cloud.e-infra.cz.

This job records a version; it does not deploy. It sends a repository_dispatch; dspace-k8s
pins the tag to git and a reconciler inside the cluster applies it. No deployment step and no cluster
credential exists in this repository — or anywhere in GitHub.

  • needs: [dspace, dspace-solr] — both images build from this same commit, so ok-dspace pins one
    SHA for the pair; waiting for both avoids dispatching a half-built version.
  • Runs only for pushes to clarin-v7 in ufal/clarin-dspace, so a pull request builds images
    but never triggers a deploy, and forks never fire it.
  • secrets.OK_DSPACE_DEPLOY_TOKEN is a fine-grained PAT scoped to ufal/dspace-k8s with
    Contents: write, which is what POST /repos/{owner}/{repo}/dispatches requires. It is already
    configured as an organisation secret. A workflow's own GITHUB_TOKEN cannot act on another
    repository, so this credential is unavoidable.

Nothing else in the build changes.

Depends on ufal/dspace-k8s#39, which defines the deploy-ok-dspace dispatch type. This PR is
inert until that merges — the dispatch simply has no listener.

…branch

Sends a repository_dispatch to ufal/dspace-k8s once the images this environment
consumes have actually been pushed. That repository pins the tag to git and an
in-cluster reconciler applies it, so this job records a version and nothing
more - no deployment step and no cluster credential exists here, or anywhere in
GitHub.

Runs only for pushes to the default branch of the canonical repository, so a
pull request builds images but never triggers a deploy.

The token is a fine-grained PAT scoped to ufal/dspace-k8s with Contents: write,
which is what POST /repos/{owner}/{repo}/dispatches requires. A workflow's own
GITHUB_TOKEN cannot act on another repository, so this credential is
unavoidable; it is held as an organisation secret shared with this repository.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the existing Docker image workflow by adding a post-build job which, on pushes to clarin-v7 in ufal/clarin-dspace, sends a repository_dispatch event to ufal/dspace-k8s so that the ok-dspace environment can pin the newly built image tag/sha.

Changes:

  • Add a deploy-ok-dspace job to .github/workflows/docker.yml gated to pushes on clarin-v7 in the upstream repo.
  • Ensure the dispatch runs only after both dspace and dspace-solr images are built/pushed (needs: [dspace, dspace-solr]).

Comment thread .github/workflows/docker.yml Outdated
Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/docker.yml Outdated
The section header said "Redeploy" and the step was called "Trigger
deployment", but this job only sends a repository_dispatch - the deploying
happens in ufal/dspace-k8s and, ultimately, in the cluster. Renamed both so the
workflow logs say what ran.

Also names `clarin-v7` explicitly instead of "the default branch", since that
is the literal value the guard matches and the two could drift apart.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

The job authenticates with a fine-grained PAT and never uses GITHUB_TOKEN, but
inherited the workflow-level permissions anyway - including `packages: write` in
dspace-angular, which it has no use for. `permissions: {}` limits what a
compromised third-party action could reach from this job.
Comment thread .github/workflows/docker.yml Outdated
permissions: {}
steps:
- name: Notify ufal/dspace-k8s
uses: peter-evans/repository-dispatch@v4

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use and action, hand roll it with curl (or gh cli if possible)

@kosarko kosarko Jul 23, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — gh it is, since ubuntu-latest ships both gh (2.96.0) and jq (1.7.1), so no download is needed either.

- name: Notify ufal/dspace-k8s
  env:
    GH_TOKEN: ${{ secrets.OK_DSPACE_DEPLOY_TOKEN }}
    SHA: ${{ github.sha }}
  run: |
    set -euo pipefail
    jq -n --arg sha "${SHA}" \
      '{event_type: "deploy-ok-dspace",
        client_payload: {component: "backend", sha: $sha}}' \
      | gh api -X POST repos/ufal/dspace-k8s/dispatches --input -

The payload is built by jq from an --arg rather than interpolated into a JSON string literal, so the value is a JSON string by construction instead of by careful quoting. Verified the emitted payload carries the same fields and values the action was sending, so nothing changes on the receiving end in pin-ok-dspace.yml. (Same JSON, not the same bytes — jq pretty-prints where the action sent compact; the API parses either.) gh api exits non-zero on an HTTP error, so a rejected dispatch still fails the job.

The real gain is that the PAT is no longer in the environment of third-party code for the sake of one POST. I also fixed the permissions: {} comment, which justified itself by "limits what a compromised third-party action could reach" — there is no longer one. Least privilege still applies, just for the plain reason that this job authenticates with the PAT and never touches GITHUB_TOKEN.

actionlint with shellcheck is clean.

peter-evans/repository-dispatch@v4 ran with the deploy PAT in its
environment to make a single POST. ubuntu-latest already ships gh and
jq, so the same call is three lines with no third-party code in the
credential's blast radius.

jq builds the payload from an --arg rather than interpolating the sha
into a JSON string, so the value is a JSON string by construction. The
request body is identical to what the action sent.

The permissions comment no longer justifies itself by third-party
actions, since there are none here now; permissions: {} still stands on
its own, because the job authenticates with the PAT and never touches
GITHUB_TOKEN.
@kosarko
kosarko marked this pull request as ready for review July 23, 2026 11:56
@kosarko
kosarko merged commit 99bf59d into clarin-v7 Jul 23, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants