Skip to content

openapi: Add openapi/upload composite action#208

Open
reakaleek wants to merge 4 commits into
mainfrom
openapi-upload-action
Open

openapi: Add openapi/upload composite action#208
reakaleek wants to merge 4 commits into
mainfrom
openapi-upload-action

Conversation

@reakaleek

@reakaleek reakaleek commented Jul 3, 2026

Copy link
Copy Markdown
Member

Closes https://github.com/elastic/docs-eng-team/issues/640

What

Adds openapi/upload, a composite action that uploads an already-linted, already-bundled OpenAPI spec to S3 via OIDC.

Why

Foundation work for the OpenAPI-specs-to-S3 rollout — RFC elastic/docs-eng-team#634, tracked by elastic/docs-eng-team#640. All per-repo adoption is blocked on this action existing.

How

  • Composite action mirrors changelog/upload and changelog/bundle-upload: an inline bash validation step (reject absolute paths, .., newlines), then aws/auth@v1 with a new elastic-docs-openapi- role-name prefix, then aws s3 cp --checksum-algorithm SHA256 with the correct content-type.
  • Bucket (elastic-docs-openapi-specs), account, region, and role-prefix defaults match what's provisioned in elastic/docs-infra#339.
  • Resolves the upload key as <s3-prefix>/<version>/<spec-name>.<ext>, defaulting prefix to ${{ github.repository }} (required — IAM only grants s3:PutObject under that prefix) and version to the triggering branch, overridable for repos like elastic/cloud with non-standard branch names.
  • Does not lint and does not bundle — those are the consumer's responsibility before calling this action (openapi/lint is a separate action; bundling e.g. via redocly bundle happens in the consumer's own workflow step). README documents the two-workflow (PR lint / publish-on-merge) integration pattern from the RFC.

Test plan

  • pre-commit runcheck-yaml, action-readme pass; README tables regenerate with no drift
  • Extracted the validate-inputs bash and ran it standalone against: happy path (.yaml/.json), absolute path, .., newline, empty spec-name, bad extension, missing file — all pass/fail as expected
  • Manually resolved the upload command/key for a sample input and confirmed it matches the RFC's example key exactly (s3://elastic-docs-openapi-specs/elastic/kibana/main/kibana.yaml)
  • Real end-to-end S3 upload — blocked on elastic/docs-infra#339 (bucket + OIDC roles) merging

Notes

Acceptance criteria in elastic/docs-eng-team#640 mention bundling inside this action; per discussion, bundling was moved to the consumer's responsibility instead, so this action only validates, authenticates, and uploads.

Foundation for the OpenAPI-specs-to-S3 rollout (RFC elastic/docs-eng-team#634,
tracked by elastic/docs-eng-team#640). Uploads an already-linted,
already-bundled spec to S3 via OIDC, using the same role-derivation scheme
as aws/auth and the bucket/role scoping provisioned in
elastic/docs-infra#339.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@reakaleek reakaleek requested a review from a team as a code owner July 3, 2026 11:58
@reakaleek reakaleek requested a review from cotti July 3, 2026 11:58
@reakaleek reakaleek added the enhancement New feature or request label Jul 3, 2026
Replace the path-traversal validator on spec-name/version with the
single-segment allowlist regex already used for artifact-name in
changelog/bundle-upload — the path validator only rejected a leading
"/" and literal "..", so an embedded slash (e.g. spec-name: foo/bar)
silently produced a nested S3 key the layout doesn't intend. Also
collapse the duplicated yaml/yml case branches (ext is now derived
from the path suffix) and trim README prose that just restated the
generated input descriptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@reakaleek reakaleek self-assigned this Jul 3, 2026
Comment thread openapi/upload/README.md Outdated
<!-- Generated by https://github.com/reakaleek/gh-action-readme -->
# <!--name-->OpenAPI upload<!--/name-->
<!--description-->
Uploads an already-linted, already-bundled OpenAPI spec to S3 (elastic-docs-openapi-specs) via OIDC. Does not lint and does not bundle — the consumer workflow is responsible for both before calling this action. Part of the RFC for publishing OpenAPI specs to S3 (elastic/docs-eng-team#634).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

At what point should we catch non-linted or non-bundled specs? Does the process rely entirely on trust and correct behaviour prior to upload?

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.

It's a good point. Thank you.. I was thinking of adding a step here that runs the lint right before upload.

But this would depend on #207 to get merged first.

I would definitely handle it as follow-up.

@reakaleek reakaleek Jul 3, 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.

In general, these actions were meant to be part of a broader reusable workflow that orechestrates the usage of these actions.

But i'm starting to think that every repository generates the OAS so differently that it's not feasible to create a reusable workflow from the get go..

Maybe in a refactoring follow-up after learning how it works today.

reakaleek and others added 2 commits July 3, 2026 15:07
Drop the RFC/issue reference and the redundant bucket name (already
the s3-bucket input's default) from the description.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mirror validate_path with a validate_segment helper instead of bare
if-blocks, so the two validation shapes (path-like vs. single-segment)
read the same way at the call sites.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@cotti cotti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM mostly, just want to confirm one point

Comment thread openapi/upload/action.yml
S3_PREFIX: ${{ inputs.s3-prefix }}
VERSION: ${{ inputs.version }}
run: |
validate_path() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's missing a symlink check for this. It could have a

  if [[ -L "$SPEC_PATH" ]]; then
    echo "::error::spec-path must not be a symlink: ${SPEC_PATH}"; exit 1
  fi

or maybe reuse the Reject symlink step on docs-deploy?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants