Skip to content

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

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#175
kosarko merged 4 commits into
clarin-v7from
cicd/dispatch-ok-dspace

Conversation

@kosarko

@kosarko kosarko commented Jul 22, 2026

Copy link
Copy Markdown
Member

Replaces the commented-out deploy: stub with a deploy-ok-dspace job that notifies
ufal/dspace-k8s once the image this test environment consumes
has been pushed. Target environment: https://ok-dspace.dyn.cloud.e-infra.cz.

The old stub targeted the dataquest docker-compose instances (dev-5/dev-8) we no longer have
access to, which is why it was commented out rather than maintained.

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-angular-dist], not dspace-angular — the latter builds the -dev suffixed
    image, while the overlay runs the unsuffixed dist image. Easy to get backwards.
  • Runs only for pushes to clarin-v7 in ufal/dspace-angular, so a pull request builds the
    image 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.

Worth knowing: the deploy verification on the other side reads this application's commit from
/static/VERSION_D, which scripts/sourceversion.py generates at image build time — so that script
staying wired up in docker.yml is now load-bearing for confirming a deploy actually landed.

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

…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 updates the Docker image workflow to notify ufal/dspace-k8s (via repository_dispatch) after the ufal/dspace-angular dist image has been pushed on pushes to clarin-v7, enabling ok-dspace’s cluster-side reconciler to pick up and apply the new version.

Changes:

  • Replaces the old commented-out deploy stub with a real deploy-ok-dspace job.
  • Gates the notification job to only run on pushes to clarin-v7 in ufal/dspace-angular and only after dspace-angular-dist completes.
  • Triggers ufal/dspace-k8s via peter-evans/repository-dispatch@v4 with a payload containing the frontend component and commit SHA.

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 1 comment.

Comment thread .github/workflows/docker.yml
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: "frontend", 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 12:17
@kosarko
kosarko merged commit d4868c3 into clarin-v7 Jul 23, 2026
7 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