diff --git a/openapi/upload/README.md b/openapi/upload/README.md index fce70101..1d098ead 100644 --- a/openapi/upload/README.md +++ b/openapi/upload/README.md @@ -13,6 +13,8 @@ Uploads an already-linted, already-bundled OpenAPI spec to S3 via OIDC. Does not | `s3-bucket` | Target S3 bucket. Only override if a different bucket has been provisioned. | `false` | `elastic-docs-openapi-specs` | | `s3-prefix` | Key prefix under the bucket. Defaults to "/", which is also the prefix the OIDC role is scoped to write — only override within that same repo prefix, or the upload will be denied.
| `false` | `${{ github.repository }}` | | `version` | Version segment of the key. Defaults to the triggering branch name. Override for repos whose branch names do not match the RFC convention (e.g. elastic/cloud, whose default branch is "master" and whose release branches are named "ECE-4.1").
| `false` | `${{ github.ref_name }}` | +| `branch` | Git branch that triggered the upload. Stored as S3 object metadata, not used in the object key. Defaults to the triggering branch name.
| `false` | `${{ github.ref_name }}` | +| `commit` | Full git commit SHA that produced the uploaded spec. | `false` | `${{ github.sha }}` | | `aws-region` | The AWS region to use | `false` | `us-east-1` | | `aws-account-id` | The AWS account ID. Only override if OIDC trust and IAM roles have been provisioned for the target account. | `false` | `197730964718` | @@ -52,7 +54,8 @@ jobs: - uses: elastic/docs-actions/openapi/upload@v1 with: spec-path: openapi.yaml - # uploads to elastic///openapi.yaml + # uploads to s3://elastic-docs-openapi-specs////openapi.yaml + # metadata: x-amz-meta-commit, x-amz-meta-repository, x-amz-meta-branch ``` **Multiple specs** (e.g. Kibana's stateful and serverless specs): add a separate publish job per spec, setting `spec-name` per job: @@ -65,11 +68,14 @@ jobs: # uploads to elastic/kibana//kibana.yaml ``` -**Non-standard branch names**: repos like `elastic/cloud` (default branch `master`, release branches named `ECE-4.1`) must set `version` explicitly: +**Non-standard branch names**: repos like `elastic/cloud` (default branch `master`, release branches named `ECE-4.1`) must set `version` explicitly. `branch` defaults to `github.ref_name` and is stored as object metadata, so it records the real git ref even when `version` differs: ```yaml - uses: elastic/docs-actions/openapi/upload@v1 with: spec-path: openapi.yaml - version: ${{ github.ref_name == 'master' && 'main' || github.ref_name }} + version: ${{ github.ref_name == 'master' && 'main' || startsWith(github.ref_name, 'ECE-') && replace(github.ref_name, 'ECE-', '') || github.ref_name }} + # branch defaults to github.ref_name — metadata records ECE-4.1, key uses 4.1 ``` + +Each uploaded object sets S3 user metadata: `x-amz-meta-commit`, `x-amz-meta-repository` (same value as `s3-prefix`), and `x-amz-meta-branch` (same value as `branch`). Read these with `HeadObject` without parsing the object key. diff --git a/openapi/upload/action.yml b/openapi/upload/action.yml index 15073ec2..2b18ca9e 100644 --- a/openapi/upload/action.yml +++ b/openapi/upload/action.yml @@ -28,6 +28,14 @@ inputs: (e.g. elastic/cloud, whose default branch is "master" and whose release branches are named "ECE-4.1"). default: '${{ github.ref_name }}' + branch: + description: > + Git branch that triggered the upload. Stored as S3 object metadata, not + used in the object key. Defaults to the triggering branch name. + default: '${{ github.ref_name }}' + commit: + description: 'Full git commit SHA that produced the uploaded spec.' + default: '${{ github.sha }}' aws-region: description: 'The AWS region to use' default: 'us-east-1' @@ -45,6 +53,8 @@ runs: SPEC_NAME: ${{ inputs.spec-name }} S3_PREFIX: ${{ inputs.s3-prefix }} VERSION: ${{ inputs.version }} + BRANCH: ${{ inputs.branch }} + COMMIT: ${{ inputs.commit }} run: | source "${GITHUB_ACTION_PATH}/../../scripts/validate-inputs.sh" @@ -53,6 +63,24 @@ runs: validate_segment "$SPEC_NAME" "spec-name" validate_segment "$VERSION" "version" + if [[ -z "$BRANCH" ]]; then + echo "::error::branch must not be empty" + exit 1 + fi + if [[ "$BRANCH" == *$'\n'* || "$BRANCH" == *$'\r'* ]]; then + echo "::error::branch must not contain newlines" + exit 1 + fi + if [[ "$BRANCH" =~ [[:cntrl:]] ]]; then + echo "::error::branch must not contain control characters: ${BRANCH}" + exit 1 + fi + + if [[ ! "$COMMIT" =~ ^[0-9a-f]{40}$ ]]; then + echo "::error::commit must be a 40-character lowercase hex SHA: ${COMMIT}" + exit 1 + fi + case "$SPEC_PATH" in *.yaml|*.yml) content_type=application/yaml ;; *.json) content_type=application/json ;; @@ -92,9 +120,12 @@ runs: S3_BUCKET: ${{ inputs.s3-bucket }} S3_PREFIX: ${{ inputs.s3-prefix }} VERSION: ${{ inputs.version }} + BRANCH: ${{ inputs.branch }} + COMMIT: ${{ inputs.commit }} EXT: ${{ steps.resolve.outputs.ext }} CONTENT_TYPE: ${{ steps.resolve.outputs.content-type }} run: | aws s3 cp --checksum-algorithm SHA256 --content-type "$CONTENT_TYPE" \ + --metadata "commit=${COMMIT},repository=${S3_PREFIX},branch=${BRANCH}" \ "$SPEC_PATH" \ "s3://${S3_BUCKET}/${S3_PREFIX}/${VERSION}/${SPEC_NAME}.${EXT}"