diff --git a/.gitattributes b/.gitattributes index 07764a7..56bbd5d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -* text eol=lf \ No newline at end of file +* text=auto +*.sh eol=lf \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index de38192..6c38ea8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -43,6 +43,13 @@ on: jobs: docker: runs-on: ubuntu-22.04 + + services: + registry: + image: registry:2 + ports: + - 5000:5000 + permissions: actions: read contents: write @@ -56,63 +63,103 @@ jobs: ref: ${{ github.ref_name }} fetch-depth: 0 - - name: init / inputs to env - if: github.event_name == 'workflow_dispatch' - run: | - cat << 'EOF' > .inputs - ${{ toJSON(github.event.inputs) }} - EOF - for KEY in $(cat .inputs | jq --raw-output 'keys[]' | tr '\n' ' '); do echo "input_$(echo ${KEY} | tr '[:upper:]' '[:lower:]')=$(cat .inputs | jq --raw-output '.'${KEY}'')" >> $GITHUB_ENV; done - rm -rf .inputs - - - name: init / .json to env - uses: rgarcia-phi/json-to-variables@9835d537368468c4e4de5254dc3efeadda183793 - with: - filename: '.json' - - name: init / setup environment - run: | - : # set image - LOCAL_IMAGE=${json_image} - if [ ! -z ${input_image} ]; then LOCAL_IMAGE=${input_image}; fi - echo "IMAGE=${LOCAL_IMAGE}" >> $GITHUB_ENV + uses: actions/github-script@62c3794a3eb6788d9a2a72b219504732c0c9a298 + with: + script: | + const { existsSync, readFileSync } = require('node:fs'); + const { resolve } = require('node:path'); + const inputs = `${{ toJSON(github.event.inputs) }}`; + const opt = {input:{}, dot:{}}; - : # set defaults - echo "IMAGE_ARCH=${json_arch:-linux/amd64,linux/arm64}" >> $GITHUB_ENV - echo "WORKFLOW_GITHUB_RELEASE=${input_release:-true}" >> $GITHUB_ENV; - echo "WORKFLOW_GITHUB_README=${input_readme:-true}" >> $GITHUB_ENV; - echo "WORKFLOW_GRYPE_SCAN=${json_grype_scan:-true}" >> $GITHUB_ENV; - echo "WORKFLOW_GRYPE_SEVERITY_CUTOFF=${json_grype_severity:-high}" >> $GITHUB_ENV; + try{ + if(inputs.length > 0){ + opt.input = JSON.parse(inputs); + } + }catch(e){ + core.warning('could not parse github.event.inputs'); + } - : # create tags for semver, stable and other shenanigans - LOCAL_SHA=$(git rev-parse --short HEAD) - LOCAL_SEMVER_MAJOR=$(awk -F. '{ print $1 }' <<< ${json_semver_version}) - LOCAL_SEMVER_MINOR=$(awk -F. '{ print $2 }' <<< ${json_semver_version}) - LOCAL_SEMVER_PATCH=$(awk -F. '{ print $3 }' <<< ${json_semver_version}) - LOCAL_SEMVER_PREFIX="" - LOCAL_SEMVER_SUFFIX="" - LOCAL_SEMVER_RC="" - LOCAL_TAGS="${LOCAL_IMAGE}:${LOCAL_SHA}" - if [ ! -z ${input_semverprefix} ]; then LOCAL_SEMVER_PREFIX="${input_semverprefix}-"; fi - if [ ! -z ${input_semversuffix} ]; then LOCAL_SEMVER_SUFFIX="-${input_semversuffix}"; fi - if [ ! -z ${json_semver_rc} ]; then LOCAL_SEMVER_RC="${json_semver_rc}"; fi - if [ ! -z ${LOCAL_SEMVER_MAJOR} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}${LOCAL_SEMVER_SUFFIX}"; fi - if [ ! -z ${LOCAL_SEMVER_MINOR} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}.${LOCAL_SEMVER_MINOR}${LOCAL_SEMVER_SUFFIX}"; fi - if [ ! -z ${LOCAL_SEMVER_PATCH} ]; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_SEMVER_MAJOR}.${LOCAL_SEMVER_MINOR}.${LOCAL_SEMVER_PATCH}${LOCAL_SEMVER_SUFFIX}"; fi - if echo "${LOCAL_TAGS}" | grep -q "${json_semver_stable}" ; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}stable${LOCAL_SEMVER_SUFFIX}"; fi - if echo "${LOCAL_TAGS}" | grep -q "${json_semver_latest}" ; then LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}latest${LOCAL_SEMVER_SUFFIX}"; fi - if [ ! -z ${json_semver_tags} ]; then SPECIAL_LOCAL_TAGS=$(echo ${json_semver_tags} | sed 's/,/ /g'); for LOCAL_TAG in ${json_semver_tags}; do LOCAL_TAGS="${LOCAL_TAGS},${LOCAL_IMAGE}:${LOCAL_SEMVER_PREFIX}${LOCAL_TAG}${LOCAL_SEMVER_SUFFIX}"; done; fi - echo "IMAGE_TAGS=${LOCAL_TAGS}" >> $GITHUB_ENV + try{ + const path = resolve('.json'); + if(existsSync(path)){ + try{ + opt.dot = JSON.parse(readFileSync(path).toString()); + }catch(e){ + throw new Error('could not parse .json'); + } + }else{ + throw new Error('.json does not exist'); + } + }catch(e){ + core.setFailed(e); + } - : # if for whatever reason UID/GID must be changed at build time - if [ ! -z ${input_uid} ]; then echo "IMAGE_UID=${input_uid}" >> $GITHUB_ENV; else echo "IMAGE_UID=${json_uid:-1000}" >> $GITHUB_ENV; fi - if [ ! -z ${input_gid} ]; then echo "IMAGE_GID=${input_gid}" >> $GITHUB_ENV; else echo "IMAGE_GID=${json_gid:-1000}" >> $GITHUB_ENV; fi + const docker = { + image:{ + name:(opt.input?.image || opt.dot.image), + arch:(opt.dot.arch || 'linux/amd64,linux/arm64'), + prefix:((opt.input?.semverprefix) ? `${opt.input?.semverprefix}-` : ''), + suffix:((opt.input?.semversuffix) ? `-${opt.input?.semversuffix}` : ''), + description:(opt.dot?.readme?.description || ''), + tags:[], + }, + app:{ + name:opt.dot.name, + version:opt.dot.semver.version, + root:opt.dot.root, + UID:(opt.input?.uid || 1000), + GID:(opt.input?.gid || 1000), + no_cache:new Date().getTime(), + }, + cache:{ + registry:'localhost:5000/', + } + }; - : # set rc, prefix or suffix globally for semver and version - echo "IMAGE_SEMVER_PREFIX=${LOCAL_SEMVER_PREFIX}" >> $GITHUB_ENV - echo "IMAGE_SEMVER_SUFFIX=${LOCAL_SEMVER_SUFFIX}" >> $GITHUB_ENV - echo "IMAGE_VERSION_RC=${LOCAL_SEMVER_RC}" >> $GITHUB_ENV + docker.cache.name = `${docker.image.name}:${docker.image.prefix}buildcache${docker.image.suffix}`; + docker.cache.grype = `${docker.cache.registry}${docker.image.name}:${docker.image.prefix}grype${docker.image.suffix}`; + // setup tags + const semver = opt.dot.semver.version.split('.'); + docker.image.tags.push(`${context.sha.substring(0,7)}`); + if(Array.isArray(semver)){ + if(semver.length >= 0) docker.image.tags.push(`${semver[0]}`); + if(semver.length >= 1) docker.image.tags.push(`${semver[0]}.${semver[1]}`); + if(semver.length >= 2) docker.image.tags.push(`${semver[0]}.${semver[1]}.${semver[2]}`); + } + if(opt.dot.semver?.stable && new RegExp(opt.dot.semver.stable, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('stable'); + if(opt.dot.semver?.latest && new RegExp(opt.dot.semver.latest, 'ig').test(docker.image.tags.join(','))) docker.image.tags.push('latest'); + + for(let i=0; i> ${GITHUB_OUTPUT} - name: github / release / markdown - if: env.WORKFLOW_GITHUB_RELEASE == 'true' + if: env.WORKFLOW_CREATE_RELEASE == 'true' && steps.git-log.outcome == 'success' id: git-release uses: 11notes/action-docker-release@v1 with: git_log: ${{ steps.git-log.outputs.commits }} - name: github / release / create - if: env.WORKFLOW_GITHUB_RELEASE == 'true' && steps.git-release.outcome == 'success' + if: env.WORKFLOW_CREATE_RELEASE == 'true' && steps.git-release.outcome == 'success' uses: actions/create-release@4c11c9fe1dcd9636620a16455165783b20fc7ea0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -233,22 +262,26 @@ jobs: draft: false prerelease: false + + + # README - name: github / checkout master continue-on-error: true run: | git checkout master - name: github / create README.md - continue-on-error: true - if: env.WORKFLOW_GITHUB_README == 'true' id: github-readme + continue-on-error: true + if: env.WORKFLOW_CREATE_README == 'true' && steps.docker-build.outcome == 'success' uses: 11notes/action-docker-readme@v1 with: - sarif_file: ${{ steps.grype-scan.outputs.sarif }} + sarif_file: ${{ steps.grype.outputs.sarif }} + build_output_metadata: ${{ steps.docker-build.outputs.metadata }} - name: github / commit & push continue-on-error: true - if: steps.github-readme.outcome == 'success' + if: steps.github-readme.outcome == 'success' && hashFiles('README.md') != '' run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" @@ -257,17 +290,21 @@ jobs: git push - name: docker / push README.md to docker hub - if: hashFiles('README.md') != '' + continue-on-error: true + if: steps.github-readme.outcome == 'success' && hashFiles('README.md') != '' uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 env: DOCKER_USER: 11notes DOCKER_PASS: ${{ secrets.DOCKER_TOKEN }} with: - destination_container_repo: ${{ env.IMAGE }} + destination_container_repo: ${{ env.DOCKER_IMAGE_NAME }} provider: dockerhub - short_description: ${{ env.json_readme_description }} + short_description: ${{ env.DOCKER_IMAGE_DESCRIPTION }} readme_file: 'README.md' + + + # REPOSITORY SETTINGS - name: github / update description and set repo defaults run: | curl --request PATCH \ @@ -275,7 +312,7 @@ jobs: --header 'authorization: Bearer ${{ secrets.REPOSITORY_TOKEN }}' \ --header 'content-type: application/json' \ --data '{ - "description":"${{ env.json_readme_description }}", + "description":"${{ env.DOCKER_IMAGE_DESCRIPTION }}", "homepage":"", "has_issues":true, "has_discussions":true,