mirror of
https://github.com/redhat-actions/push-to-registry.git
synced 2025-02-22 10:11:21 +01:00
Check and enforce lowercasing of registry and image refs. (#56)
This commit is contained in:
parent
7e7aa10ef2
commit
ac5a9d0fd8
4 changed files with 96 additions and 16 deletions
65
.github/workflows/check-lowercase.yaml
vendored
Normal file
65
.github/workflows/check-lowercase.yaml
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
# This workflow will perform a test whenever there
|
||||
# is some change in code done to ensure that the changes
|
||||
# are not buggy and we are getting the desired output.
|
||||
name: Check Case Normalization
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # every day at midnight
|
||||
env:
|
||||
IMAGE_NAME: ImageCaseTest
|
||||
IMAGE_TAGS: v1 TagCaseTest ${{ github.sha }}
|
||||
IMAGE_REGISTRY: Ghcr.io/${{ github.repository_owner }}
|
||||
REGISTRY_USER: ${{ github.actor }}
|
||||
REGISTRY_PASSWORD: ${{ github.token }}
|
||||
|
||||
jobs:
|
||||
push-ghcr:
|
||||
name: Build and push image
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
install_latest: [ true, false ]
|
||||
|
||||
steps:
|
||||
# Checkout push-to-registry action github repository
|
||||
- name: Checkout Push to Registry action
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install latest podman
|
||||
if: matrix.install_latest
|
||||
run: |
|
||||
bash .github/install_latest_podman.sh
|
||||
|
||||
# Build image using Buildah action
|
||||
- name: Build Image
|
||||
id: build_image
|
||||
uses: redhat-actions/buildah-build@v2
|
||||
with:
|
||||
image: ${{ env.IMAGE_NAME }}
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
base-image: busybox:latest
|
||||
entrypoint: |
|
||||
bash
|
||||
-c
|
||||
echo 'hello world'
|
||||
oci: true
|
||||
|
||||
# Push the image to GHCR (Image Registry)
|
||||
- name: Push To GHCR
|
||||
uses: ./
|
||||
id: push
|
||||
with:
|
||||
image: ${{ steps.build_image.outputs.image }}
|
||||
tags: ${{ steps.build_image.outputs.tags }}
|
||||
registry: ${{ env.IMAGE_REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USER }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
extra-args: |
|
||||
--disable-content-trust
|
||||
|
||||
- name: Echo outputs
|
||||
run: |
|
||||
echo "${{ toJSON(steps.push.outputs) }}"
|
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
43
src/index.ts
43
src/index.ts
|
@ -43,7 +43,7 @@ async function getPodmanPath(): Promise<string> {
|
|||
|
||||
async function run(): Promise<void> {
|
||||
const DEFAULT_TAG = "latest";
|
||||
const imageInput = core.getInput(Inputs.IMAGE);
|
||||
const image = core.getInput(Inputs.IMAGE);
|
||||
const tags = core.getInput(Inputs.TAGS);
|
||||
// split tags
|
||||
const tagsList = tags.trim().split(/\s+/);
|
||||
|
@ -53,6 +53,21 @@ async function run(): Promise<void> {
|
|||
core.info(`Input "${Inputs.TAGS}" is not provided, using default tag "${DEFAULT_TAG}"`);
|
||||
tagsList.push(DEFAULT_TAG);
|
||||
}
|
||||
|
||||
const normalizedTagsList: string[] = [];
|
||||
let isNormalized = false;
|
||||
for (const tag of tagsList) {
|
||||
normalizedTagsList.push(tag.toLowerCase());
|
||||
if (tag.toLowerCase() !== tag) {
|
||||
isNormalized = true;
|
||||
}
|
||||
}
|
||||
const normalizedImage = image.toLowerCase();
|
||||
if (isNormalized || image !== normalizedImage) {
|
||||
core.warning(`Reference to image and/or tag must be lowercase.`
|
||||
+ ` Reference has been converted to be compliant with standard.`);
|
||||
}
|
||||
|
||||
const registry = core.getInput(Inputs.REGISTRY);
|
||||
const username = core.getInput(Inputs.USERNAME);
|
||||
const password = core.getInput(Inputs.PASSWORD);
|
||||
|
@ -60,12 +75,12 @@ async function run(): Promise<void> {
|
|||
const digestFileInput = core.getInput(Inputs.DIGESTFILE);
|
||||
|
||||
// check if all tags provided are in `image:tag` format
|
||||
const isFullImageNameTag = isFullImageName(tagsList[0]);
|
||||
if (tagsList.some((tag) => isFullImageName(tag) !== isFullImageNameTag)) {
|
||||
const isFullImageNameTag = isFullImageName(normalizedTagsList[0]);
|
||||
if (normalizedTagsList.some((tag) => isFullImageName(tag) !== isFullImageNameTag)) {
|
||||
throw new Error(`Input "${Inputs.TAGS}" cannot have a mix of full name and non full name tags`);
|
||||
}
|
||||
if (!isFullImageNameTag) {
|
||||
if (!imageInput) {
|
||||
if (!normalizedImage) {
|
||||
throw new Error(`Input "${Inputs.IMAGE}" must be provided when using non full name tags`);
|
||||
}
|
||||
if (!registry) {
|
||||
|
@ -73,28 +88,28 @@ async function run(): Promise<void> {
|
|||
}
|
||||
|
||||
const registryWithoutTrailingSlash = registry.replace(/\/$/, "");
|
||||
const registryPath = `${registryWithoutTrailingSlash}/${imageInput}`;
|
||||
core.info(`Combining image name "${imageInput}" and registry "${registry}" `
|
||||
const registryPath = `${registryWithoutTrailingSlash}/${normalizedImage}`;
|
||||
core.info(`Combining image name "${normalizedImage}" and registry "${registry}" `
|
||||
+ `to form registry path "${registryPath}"`);
|
||||
if (imageInput.indexOf("/") > -1 && registry.indexOf("/") > -1) {
|
||||
if (normalizedImage.indexOf("/") > -1 && registry.indexOf("/") > -1) {
|
||||
core.warning(`"${registryPath}" does not seem to be a valid registry path. `
|
||||
+ `The registry path should not contain more than 2 slashes. `
|
||||
+ `Refer to the Inputs section of the readme for naming image and registry.`);
|
||||
}
|
||||
|
||||
sourceImages = tagsList.map((tag) => getFullImageName(imageInput, tag));
|
||||
destinationImages = tagsList.map((tag) => getFullImageName(registryPath, tag));
|
||||
sourceImages = normalizedTagsList.map((tag) => getFullImageName(normalizedImage, tag));
|
||||
destinationImages = normalizedTagsList.map((tag) => getFullImageName(registryPath, tag));
|
||||
}
|
||||
else {
|
||||
if (imageInput) {
|
||||
if (normalizedImage) {
|
||||
core.warning(`Input "${Inputs.IMAGE}" is ignored when using full name tags`);
|
||||
}
|
||||
if (registry) {
|
||||
core.warning(`Input "${Inputs.REGISTRY}" is ignored when using full name tags`);
|
||||
}
|
||||
|
||||
sourceImages = tagsList;
|
||||
destinationImages = tagsList;
|
||||
sourceImages = normalizedTagsList;
|
||||
destinationImages = normalizedTagsList;
|
||||
}
|
||||
|
||||
const inputExtraArgsStr = core.getInput(Inputs.EXTRA_ARGS);
|
||||
|
@ -157,8 +172,8 @@ async function run(): Promise<void> {
|
|||
);
|
||||
}
|
||||
|
||||
const allTagsinPodman: boolean = podmanFoundTags.length === tagsList.length;
|
||||
const allTagsinDocker: boolean = dockerFoundTags.length === tagsList.length;
|
||||
const allTagsinPodman: boolean = podmanFoundTags.length === normalizedTagsList.length;
|
||||
const allTagsinDocker: boolean = dockerFoundTags.length === normalizedTagsList.length;
|
||||
|
||||
if (allTagsinPodman && allTagsinDocker) {
|
||||
const isPodmanImageLatest = await isPodmanLocalImageLatest();
|
||||
|
|
Loading…
Add table
Reference in a new issue