Skip to content

Commit

Permalink
feat: Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeluxe committed Jul 24, 2023
1 parent 332104b commit 7e6c62c
Show file tree
Hide file tree
Showing 10 changed files with 1,298 additions and 0 deletions.
98 changes: 98 additions & 0 deletions .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Docker

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
push:
branches: [ "main" ]
# Publish semver tags as releases.
tags: [ '*.*.*' ]
pull_request:
branches: [ "main" ]

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}


jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@f3c664df7af409cb4873aa5068053ba9d61a57b6 #v2.6.0
with:
cosign-release: 'v1.13.1'

# Set up QEMU to be able to build to multiple architectures
- name: Set up QEMU
uses: docker/setup-qemu-action@v1

# Workaround: https://github.com/docker/build-push-action/issues/461
- name: Setup Docker buildx
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64


# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
COSIGN_EXPERIMENTAL: "true"
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} cosign sign {}@${{ steps.build-and-push.outputs.digest }}
124 changes: 124 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
**/*.js
!jest.config.js
!.eslintrc.js

### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# Compiled typescript
dist/
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm install \
&& npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder ./app/dist ./dist
COPY package.json .
RUN npm install --production
CMD ["npm", "run" ,"start"]
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Sonatype Nexus Repository Manager custom cleanup

## Introduction

Sonatype Nexus Repository Manager natively only offers cleanup based on the age of a component or the last download date
of a component.

We have the requirement to do a cleanup based on the (maven) path depth and to keep the n youngest components. This tool
implements this requirement.

## Usage

The docker based used is recommended, but if required it can also be used as a node application directly:

### Configuration

These are the variables to configure the application with:

| Variable | description | Required | Default value |
|----------------|-----------------------------------------------------------------------------|----------|---------------|
| NEXUS_URL | Nexus base URL without trailing slash | yes | |
| NEXUS_USERNAME | Nexus user (needs permissions to read and delete components for given repo) | yes | |
| NEXUS_PASSWORD | Password for that Nexus User | yes | |
| REPO_NAME | Name of the repo to cleanup components for | yes | |
| KEEP_ITEMS | Keep this amount of items for given path depth | yes | |
| PATH_DEPTH | Path depth to do cleanup for | yes | |
| EXECUTE_DELETE | If false, only print components to delete, instead of really deleting them | no | "false" |
| LOG_LEVEL | Log level for logging | no | "info" |


### Docker

#### Build

You can build the docker image by yourself with typical docker build commands:

docker build -t nexus-custom-cleanup:latest .

but it is recommended to use the released docker images from the GitHub registry in this repo.

#### Run

The container started using this image will terminate, after the cleanup is completed. It does not run as daemon and
does not provide any cron- or interval-like scheduling. Please implement a reoccuring run by yourself, if required.

The container needs to be run with the configuration (see above) set as environment variables.

An example execution could be:

docker run -it --rm -e NEXUS_URL="https://nexus.copany.com" -e NEXUS_USERNAME="nexususer" -e NEXUS_PASSWORD="XXXXXXXXX" -e REPO_NAME="application-snapshots-maven-hosted" -e KEEP_ITEMS=4 -e PATH_DEPTH=7 -e EXECUTE_DELETE="false" nexus-custom-cleanup:latest

### Native node application

For this it is required that NodeJS is installed on your system already.

Instead of using docker, the solution can be used as a node application directly, be sure to build it first before using
it:

npm install
npm run build

You can either set the needed configuration parameters (see above) via environment variables or via an .env file. If you
use a .env file, place it in same directory like this README.md

Example call to start the application (it will terminate once the cleanup is completed):

npm run start

# Development

For development you need to install typescript and before executing the generated javascript you need to generate it
before your first run and after every change with

npm run build

in the same directory like this README.md. Typescript code can be found in the src/ directory. Code in dist/ will be overwritten by the code
generation
Loading

0 comments on commit 7e6c62c

Please sign in to comment.