mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Merge pull request #761 from paperless-ngx/feature-build-all-images
Update GHA workflow to build all Docker images
This commit is contained in:
commit
f9194bd28c
9
.build-config.json
Normal file
9
.build-config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"qpdf": {
|
||||
"version": "10.6.3"
|
||||
},
|
||||
"jbig2enc": {
|
||||
"version": "0.29",
|
||||
"git_tag": "0.29"
|
||||
}
|
||||
}
|
@ -33,5 +33,5 @@ indent_style = space
|
||||
[**/test_*.py]
|
||||
max_line_length = off
|
||||
|
||||
[Dockerfile]
|
||||
[Dockerfile*]
|
||||
indent_style = space
|
||||
|
343
.github/workflows/ci.yml
vendored
343
.github/workflows/ci.yml
vendored
@ -45,73 +45,155 @@ jobs:
|
||||
name: documentation
|
||||
path: docs/_build/html/
|
||||
|
||||
code-checks-backend:
|
||||
name: "Backend Code Checks"
|
||||
ci-backend:
|
||||
uses: ./.github/workflows/reusable-ci-backend.yml
|
||||
|
||||
ci-frontend:
|
||||
uses: ./.github/workflows/reusable-ci-frontend.yml
|
||||
|
||||
prepare-docker-build:
|
||||
name: Prepare Docker Pipeline Data
|
||||
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/beta' || startsWith(github.ref, 'refs/tags/ngx-') || startsWith(github.ref, 'refs/tags/beta-'))
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- documentation
|
||||
- ci-backend
|
||||
- ci-frontend
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Install checkers
|
||||
run: |
|
||||
pipx install reorder-python-imports
|
||||
pipx install yesqa
|
||||
pipx install add-trailing-comma
|
||||
pipx install flake8
|
||||
-
|
||||
name: Run reorder-python-imports
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs reorder-python-imports
|
||||
-
|
||||
name: Run yesqa
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs yesqa
|
||||
-
|
||||
name: Run add-trailing-comma
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs add-trailing-comma
|
||||
# black is placed after add-trailing-comma because it may format differently
|
||||
# if a trailing comma is added
|
||||
-
|
||||
name: Run black
|
||||
uses: psf/black@stable
|
||||
name: Login to Github Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
options: "--check --diff"
|
||||
version: "22.3.0"
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Run flake8 checks
|
||||
run: |
|
||||
cd src/
|
||||
flake8 --max-line-length=88 --ignore=E203,W503
|
||||
|
||||
code-checks-frontend:
|
||||
name: "Frontend Code Checks"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
python-version: "3.9"
|
||||
-
|
||||
name: Install prettier
|
||||
name: Make script executable
|
||||
run: |
|
||||
npm install prettier
|
||||
chmod +x ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py
|
||||
-
|
||||
name: Run prettier
|
||||
run:
|
||||
npx prettier --check --ignore-path Pipfile.lock **/*.js **/*.ts *.md **/*.md
|
||||
name: Setup qpdf image
|
||||
id: qpdf-setup
|
||||
run: |
|
||||
build_json=$(python ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py qpdf)
|
||||
|
||||
tests-backend:
|
||||
needs: [code-checks-backend]
|
||||
name: "Backend Tests (${{ matrix.python-version }})"
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10']
|
||||
fail-fast: false
|
||||
echo ${build_json}
|
||||
|
||||
echo ::set-output name=qpdf-json::${build_json}
|
||||
-
|
||||
name: Setup psycopg2 image
|
||||
id: psycopg2-setup
|
||||
run: |
|
||||
build_json=$(python ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py psycopg2)
|
||||
|
||||
echo ${build_json}
|
||||
|
||||
echo ::set-output name=psycopg2-json::${build_json}
|
||||
-
|
||||
name: Setup pikepdf image
|
||||
id: pikepdf-setup
|
||||
run: |
|
||||
build_json=$(python ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py pikepdf)
|
||||
|
||||
echo ${build_json}
|
||||
|
||||
echo ::set-output name=pikepdf-json::${build_json}
|
||||
-
|
||||
name: Setup jbig2enc image
|
||||
id: jbig2enc-setup
|
||||
run: |
|
||||
build_json=$(python ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py jbig2enc)
|
||||
|
||||
echo ${build_json}
|
||||
|
||||
echo ::set-output name=jbig2enc-json::${build_json}
|
||||
-
|
||||
name: Setup frontend image
|
||||
id: frontend-setup
|
||||
run: |
|
||||
build_json=$(python ${GITHUB_WORKSPACE}/docker-builders/get-build-json.py frontend)
|
||||
|
||||
echo ${build_json}
|
||||
|
||||
echo ::set-output name=frontend-json::${build_json}
|
||||
|
||||
outputs:
|
||||
|
||||
qpdf-json: ${{ steps.qpdf-setup.outputs.qpdf-json }}
|
||||
|
||||
pikepdf-json: ${{ steps.pikepdf-setup.outputs.pikepdf-json }}
|
||||
|
||||
psycopg2-json: ${{ steps.psycopg2-setup.outputs.psycopg2-json }}
|
||||
|
||||
jbig2enc-json: ${{ steps.jbig2enc-setup.outputs.jbig2enc-json}}
|
||||
|
||||
frontend-json: ${{ steps.frontend-setup.outputs.frontend-json}}
|
||||
|
||||
build-qpdf-debs:
|
||||
name: qpdf
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
uses: ./.github/workflows/reusable-workflow-builder.yml
|
||||
with:
|
||||
dockerfile: ./docker-builders/Dockerfile.qpdf
|
||||
build-json: ${{ needs.prepare-docker-build.outputs.qpdf-json }}
|
||||
build-args: |
|
||||
QPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).version }}
|
||||
|
||||
build-jbig2enc:
|
||||
name: jbig2enc
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
uses: ./.github/workflows/reusable-workflow-builder.yml
|
||||
with:
|
||||
dockerfile: ./docker-builders/Dockerfile.jbig2enc
|
||||
build-json: ${{ needs.prepare-docker-build.outputs.jbig2enc-json }}
|
||||
build-args: |
|
||||
JBIG2ENC_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.jbig2enc-json).version }}
|
||||
|
||||
build-psycopg2-wheel:
|
||||
name: psycopg2
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
uses: ./.github/workflows/reusable-workflow-builder.yml
|
||||
with:
|
||||
dockerfile: ./docker-builders/Dockerfile.psycopg2
|
||||
build-json: ${{ needs.prepare-docker-build.outputs.psycopg2-json }}
|
||||
build-args: |
|
||||
PSYCOPG2_GIT_TAG=${{ fromJSON(needs.prepare-docker-build.outputs.psycopg2-json).git_tag }}
|
||||
PSYCOPG2_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.psycopg2-json).version }}
|
||||
|
||||
build-pikepdf-wheel:
|
||||
name: pikepdf
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
- build-qpdf-debs
|
||||
uses: ./.github/workflows/reusable-workflow-builder.yml
|
||||
with:
|
||||
dockerfile: ./docker-builders/Dockerfile.pikepdf
|
||||
build-json: ${{ needs.prepare-docker-build.outputs.pikepdf-json }}
|
||||
build-args: |
|
||||
REPO=${{ github.repository }}
|
||||
QPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).version }}
|
||||
PIKEPDF_GIT_TAG=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).git_tag }}
|
||||
PIKEPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).version }}
|
||||
|
||||
build-frontend:
|
||||
name: Compile frontend
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-frontend-${{ github.ref_name }}
|
||||
cancel-in-progress: false
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
@ -119,77 +201,82 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
-
|
||||
name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
-
|
||||
name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
cache: "pipenv"
|
||||
cache-dependency-path: 'Pipfile.lock'
|
||||
-
|
||||
name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript optipng libzbar0 poppler-utils
|
||||
-
|
||||
name: Install Python dependencies
|
||||
run: |
|
||||
pipenv sync --dev
|
||||
-
|
||||
name: Tests
|
||||
run: |
|
||||
cd src/
|
||||
pipenv run pytest
|
||||
-
|
||||
name: Get changed files
|
||||
name: Get changed frontend files
|
||||
id: changed-files-specific
|
||||
uses: tj-actions/changed-files@v18.1
|
||||
with:
|
||||
files: |
|
||||
src/**
|
||||
src-ui/**
|
||||
-
|
||||
name: List all changed files
|
||||
run: |
|
||||
for file in ${{ steps.changed-files-specific.outputs.all_changed_files }}; do
|
||||
echo "${file} was changed"
|
||||
done
|
||||
-
|
||||
name: Publish coverage results
|
||||
if: matrix.python-version == '3.9' && steps.changed-files-specific.outputs.any_changed == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# https://github.com/coveralls-clients/coveralls-python/issues/251
|
||||
run: |
|
||||
cd src/
|
||||
pipenv run coveralls --service=github
|
||||
|
||||
tests-frontend:
|
||||
needs: [code-checks-frontend]
|
||||
name: "Frontend Tests"
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
name: Login to Github Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cd src-ui && npm ci
|
||||
- run: cd src-ui && npm run test
|
||||
- run: cd src-ui && npm run e2e:ci
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Determine if build needed
|
||||
id: build-skip-check
|
||||
# Skip building the frontend if the tag exists and no src-ui files changed
|
||||
run: |
|
||||
if ! docker manifest inspect ${{ fromJSON(needs.prepare-docker-build.outputs.frontend-json).image_tag }} &> /dev/null ; then
|
||||
echo "Build required, no existing image"
|
||||
echo ::set-output name=frontend-build-needed::true
|
||||
elif ${{ steps.changed-files-specific.outputs.any_changed }} == 'true' ; then
|
||||
echo "Build required, src-ui changes"
|
||||
echo ::set-output name=frontend-build-needed::true
|
||||
else
|
||||
echo "No build required"
|
||||
echo ::set-output name=frontend-build-needed::false
|
||||
fi
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
if: ${{ steps.build-skip-check.outputs.frontend-build-needed == 'true' }}
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
if: ${{ steps.build-skip-check.outputs.frontend-build-needed == 'true' }}
|
||||
-
|
||||
name: Compile frontend
|
||||
uses: docker/build-push-action@v2
|
||||
if: ${{ steps.build-skip-check.outputs.frontend-build-needed == 'true' }}
|
||||
with:
|
||||
context: .
|
||||
file: ./docker-builders/Dockerfile.frontend
|
||||
tags: ${{ fromJSON(needs.prepare-docker-build.outputs.frontend-json).image_tag }}
|
||||
# The compilation is identical between different platforms
|
||||
# The buildx and QEMU setup is left, just in case that ever changes
|
||||
# But the platform is set to the runner's native for speedup
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
-
|
||||
name: Export frontend artifact from docker
|
||||
run: |
|
||||
docker create --name frontend-extract ${{ fromJSON(needs.prepare-docker-build.outputs.frontend-json).image_tag }}
|
||||
docker cp frontend-extract:/src/src/documents/static/frontend src/documents/static/frontend/
|
||||
-
|
||||
name: Upload frontend artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: frontend-compiled
|
||||
path: src/documents/static/frontend/
|
||||
|
||||
# build and push image to docker hub.
|
||||
build-docker-image:
|
||||
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/beta' || startsWith(github.ref, 'refs/tags/ngx-') || startsWith(github.ref, 'refs/tags/beta-'))
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-docker-image-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
runs-on: ubuntu-20.04
|
||||
needs: [tests-backend, tests-frontend]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-docker-image-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
needs:
|
||||
- prepare-docker-build
|
||||
- build-psycopg2-wheel
|
||||
- build-jbig2enc
|
||||
- build-qpdf-debs
|
||||
- build-pikepdf-wheel
|
||||
- build-frontend
|
||||
steps:
|
||||
-
|
||||
name: Gather Docker metadata
|
||||
@ -226,26 +313,23 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.docker-meta.outputs.tags }}
|
||||
labels: ${{ steps.docker-meta.outputs.labels }}
|
||||
build-args: |
|
||||
REPO=${{ github.repository }}
|
||||
JBIG2ENC_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.jbig2enc-json).version }}
|
||||
QPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).version }}
|
||||
PIKEPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).version }}
|
||||
PSYCOPG2_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.psycopg2-json).version }}
|
||||
FRONTEND_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.frontend-json).version }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
-
|
||||
name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ fromJSON(steps.docker-meta.outputs.json).tags[0] }}
|
||||
-
|
||||
name: Export frontend artifact from docker
|
||||
run: |
|
||||
docker create --name frontend-extract ${{ fromJSON(steps.docker-meta.outputs.json).tags[0] }}
|
||||
docker cp frontend-extract:/usr/src/paperless/src/documents/static/frontend src/documents/static/frontend/
|
||||
-
|
||||
name: Upload frontend artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: frontend-compiled
|
||||
path: src/documents/static/frontend/
|
||||
|
||||
build-release:
|
||||
needs: [build-docker-image, documentation]
|
||||
needs:
|
||||
- build-docker-image
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
@ -313,8 +397,9 @@ jobs:
|
||||
|
||||
publish-release:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: build-release
|
||||
if: contains(github.ref, 'refs/tags/ngx-') || contains(github.ref, 'refs/tags/beta-')
|
||||
needs:
|
||||
- build-release
|
||||
if: github.ref_type == 'tag' && (startsWith(github.ref_name, 'ngx-') || startsWith(github.ref_name, 'beta-'))
|
||||
steps:
|
||||
-
|
||||
name: Download release artifact
|
||||
|
108
.github/workflows/reusable-ci-backend.yml
vendored
Normal file
108
.github/workflows/reusable-ci-backend.yml
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
name: Backend CI Jobs
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
|
||||
code-checks-backend:
|
||||
name: "Code Style Checks"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Install checkers
|
||||
run: |
|
||||
pipx install reorder-python-imports
|
||||
pipx install yesqa
|
||||
pipx install add-trailing-comma
|
||||
pipx install flake8
|
||||
-
|
||||
name: Run reorder-python-imports
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs reorder-python-imports
|
||||
-
|
||||
name: Run yesqa
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs yesqa
|
||||
-
|
||||
name: Run add-trailing-comma
|
||||
run: |
|
||||
find src/ -type f -name '*.py' ! -path "*/migrations/*" | xargs add-trailing-comma
|
||||
# black is placed after add-trailing-comma because it may format differently
|
||||
# if a trailing comma is added
|
||||
-
|
||||
name: Run black
|
||||
uses: psf/black@stable
|
||||
with:
|
||||
options: "--check --diff"
|
||||
version: "22.3.0"
|
||||
-
|
||||
name: Run flake8 checks
|
||||
run: |
|
||||
cd src/
|
||||
flake8 --max-line-length=88 --ignore=E203,W503
|
||||
|
||||
tests-backend:
|
||||
name: "Tests (${{ matrix.python-version }})"
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- code-checks-backend
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10']
|
||||
fail-fast: false
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
-
|
||||
name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
-
|
||||
name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
cache: "pipenv"
|
||||
cache-dependency-path: 'Pipfile.lock'
|
||||
-
|
||||
name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript optipng libzbar0 poppler-utils
|
||||
-
|
||||
name: Install Python dependencies
|
||||
run: |
|
||||
pipenv sync --dev
|
||||
-
|
||||
name: Tests
|
||||
run: |
|
||||
cd src/
|
||||
pipenv run pytest
|
||||
-
|
||||
name: Get changed files
|
||||
id: changed-files-specific
|
||||
uses: tj-actions/changed-files@v18.1
|
||||
with:
|
||||
files: |
|
||||
src/**
|
||||
-
|
||||
name: List all changed files
|
||||
run: |
|
||||
for file in ${{ steps.changed-files-specific.outputs.all_changed_files }}; do
|
||||
echo "${file} was changed"
|
||||
done
|
||||
-
|
||||
name: Publish coverage results
|
||||
if: matrix.python-version == '3.9' && steps.changed-files-specific.outputs.any_changed == 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# https://github.com/coveralls-clients/coveralls-python/issues/251
|
||||
run: |
|
||||
cd src/
|
||||
pipenv run coveralls --service=github
|
42
.github/workflows/reusable-ci-frontend.yml
vendored
Normal file
42
.github/workflows/reusable-ci-frontend.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Frontend CI Jobs
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
|
||||
code-checks-frontend:
|
||||
name: "Code Style Checks"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
-
|
||||
name: Install prettier
|
||||
run: |
|
||||
npm install prettier
|
||||
-
|
||||
name: Run prettier
|
||||
run:
|
||||
npx prettier --check --ignore-path Pipfile.lock **/*.js **/*.ts *.md **/*.md
|
||||
tests-frontend:
|
||||
name: "Tests"
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- code-checks-frontend
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: cd src-ui && npm ci
|
||||
- run: cd src-ui && npm run test
|
||||
- run: cd src-ui && npm run e2e:ci
|
68
.github/workflows/reusable-workflow-builder.yml
vendored
Normal file
68
.github/workflows/reusable-workflow-builder.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
name: Reusable Image Builder
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
dockerfile:
|
||||
required: true
|
||||
type: string
|
||||
build-json:
|
||||
required: true
|
||||
type: string
|
||||
build-args:
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ fromJSON(inputs.build-json).name }}-${{ fromJSON(inputs.build-json).version }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build-image:
|
||||
name: Build ${{ fromJSON(inputs.build-json).name }} @ ${{ fromJSON(inputs.build-json).version }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Login to Github Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Determine if build needed
|
||||
id: build-skip-check
|
||||
run: |
|
||||
if ! docker manifest inspect ${{ fromJSON(inputs.build-json).image_tag }} &> /dev/null ; then
|
||||
echo "Building, no image exists with this version"
|
||||
echo ::set-output name=image-exists::false
|
||||
else
|
||||
echo "Not building, image exists with this version"
|
||||
echo ::set-output name=image-exists::true
|
||||
fi
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
if: ${{ steps.build-skip-check.outputs.image-exists == 'false' }}
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
if: ${{ steps.build-skip-check.outputs.image-exists == 'false' }}
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
if: ${{ steps.build-skip-check.outputs.image-exists == 'false' }}
|
||||
-
|
||||
name: Build ${{ fromJSON(inputs.build-json).name }}
|
||||
uses: docker/build-push-action@v2
|
||||
if: ${{ steps.build-skip-check.outputs.image-exists == 'false' }}
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.dockerfile }}
|
||||
tags: ${{ fromJSON(inputs.build-json).image_tag }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
build-args: ${{ inputs.build-args }}
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
@ -47,7 +47,7 @@ repos:
|
||||
- id: yesqa
|
||||
exclude: "(migrations)"
|
||||
- repo: https://github.com/asottile/add-trailing-comma
|
||||
rev: "v2.2.2"
|
||||
rev: "v2.2.3"
|
||||
hooks:
|
||||
- id: add-trailing-comma
|
||||
exclude: "(migrations)"
|
||||
@ -63,10 +63,17 @@ repos:
|
||||
hooks:
|
||||
- id: black
|
||||
# Dockerfile hooks
|
||||
- repo: https://github.com/pryorda/dockerfilelint-precommit-hooks
|
||||
rev: "v0.1.0"
|
||||
- repo: https://github.com/AleksaC/hadolint-py
|
||||
rev: v2.10.0
|
||||
hooks:
|
||||
- id: dockerfilelint
|
||||
- id: hadolint
|
||||
args:
|
||||
- --ignore
|
||||
- DL3008 # https://github.com/hadolint/hadolint/wiki/DL3008 (should probably do this at some point)
|
||||
- --ignore
|
||||
- DL3013 # https://github.com/hadolint/hadolint/wiki/DL3013 (should probably do this too at some point)
|
||||
- --ignore
|
||||
- DL3003 # https://github.com/hadolint/hadolint/wiki/DL3003 (seems excessive to use WORKDIR so much)
|
||||
# Shell script hooks
|
||||
- repo: https://github.com/lovesegfault/beautysh
|
||||
rev: v6.2.1
|
||||
|
146
Dockerfile
146
Dockerfile
@ -1,12 +1,21 @@
|
||||
FROM node:16 AS compile-frontend
|
||||
# Default to pulling from the main repo registry when manually building
|
||||
ARG REPO="paperless-ngx/paperless-ngx"
|
||||
|
||||
COPY . /src
|
||||
# These are all built previously in the pipeline
|
||||
# They provide either a .deb, .whl or whatever npm outputs
|
||||
ARG JBIG2ENC_VERSION
|
||||
ARG QPDF_VERSION
|
||||
ARG PIKEPDF_VERSION
|
||||
ARG PSYCOPG2_VERSION
|
||||
ARG FRONTEND_VERSION
|
||||
|
||||
WORKDIR /src/src-ui
|
||||
RUN npm update npm -g && npm ci --no-optional
|
||||
RUN ./node_modules/.bin/ng build --configuration production
|
||||
FROM ghcr.io/${REPO}/builder/jbig2enc:${JBIG2ENC_VERSION} as jbig2enc-builder
|
||||
FROM ghcr.io/${REPO}/builder/qpdf:${QPDF_VERSION} as qpdf-builder
|
||||
FROM ghcr.io/${REPO}/builder/pikepdf:${PIKEPDF_VERSION} as pikepdf-builder
|
||||
FROM ghcr.io/${REPO}/builder/psycopg2:${PSYCOPG2_VERSION} as psycopg2-builder
|
||||
FROM ghcr.io/${REPO}/builder/frontend:${FRONTEND_VERSION} as compile-frontend
|
||||
|
||||
FROM ghcr.io/paperless-ngx/builder/ngx-base:1.7.0 as main-app
|
||||
FROM python:3.9-slim-bullseye as main-app
|
||||
|
||||
LABEL org.opencontainers.image.authors="paperless-ngx team <hello@paperless-ngx.com>"
|
||||
LABEL org.opencontainers.image.documentation="https://paperless-ngx.readthedocs.io/en/latest/"
|
||||
@ -14,27 +23,115 @@ LABEL org.opencontainers.image.source="https://github.com/paperless-ngx/paperles
|
||||
LABEL org.opencontainers.image.url="https://github.com/paperless-ngx/paperless-ngx"
|
||||
LABEL org.opencontainers.image.licenses="GPL-3.0-only"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Packages needed only for building
|
||||
ARG BUILD_PACKAGES="\
|
||||
build-essential \
|
||||
git \
|
||||
python3-dev"
|
||||
|
||||
# Packages need for running
|
||||
ARG RUNTIME_PACKAGES="\
|
||||
curl \
|
||||
file \
|
||||
# fonts for text file thumbnail generation
|
||||
fonts-liberation \
|
||||
gettext \
|
||||
ghostscript \
|
||||
gnupg \
|
||||
gosu \
|
||||
icc-profiles-free \
|
||||
imagemagick \
|
||||
media-types \
|
||||
liblept5 \
|
||||
libpq5 \
|
||||
libxml2 \
|
||||
libxslt1.1 \
|
||||
libgnutls30 \
|
||||
libjpeg62-turbo \
|
||||
optipng \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
postgresql-client \
|
||||
# For Numpy
|
||||
libatlas3-base \
|
||||
# thumbnail size reduction
|
||||
pngquant \
|
||||
# OCRmyPDF dependencies
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-eng \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-fra \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-spa \
|
||||
tzdata \
|
||||
unpaper \
|
||||
# Mime type detection
|
||||
zlib1g \
|
||||
# Barcode splitter
|
||||
libzbar0 \
|
||||
poppler-utils"
|
||||
|
||||
WORKDIR /usr/src/paperless/src/
|
||||
|
||||
# Copy qpdf and runtime library
|
||||
COPY --from=qpdf-builder /usr/src/qpdf/libqpdf28_*.deb ./
|
||||
COPY --from=qpdf-builder /usr/src/qpdf/qpdf_*.deb ./
|
||||
|
||||
# Copy pikepdf wheel and dependencies
|
||||
COPY --from=pikepdf-builder /usr/src/pikepdf/wheels/*.whl ./
|
||||
|
||||
# Copy psycopg2 wheel
|
||||
COPY --from=psycopg2-builder /usr/src/psycopg2/wheels/psycopg2*.whl ./
|
||||
|
||||
# copy jbig2enc
|
||||
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/.libs/libjbig2enc* /usr/local/lib/
|
||||
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/jbig2 /usr/local/bin/
|
||||
COPY --from=jbig2enc-builder /usr/src/jbig2enc/src/*.h /usr/local/include/
|
||||
|
||||
COPY requirements.txt ../
|
||||
|
||||
# Python dependencies
|
||||
RUN apt-get update \
|
||||
# python-Levenshtein still needs to be compiled here
|
||||
&& apt-get -y --no-install-recommends install \
|
||||
build-essential \
|
||||
&& python3 -m pip install --upgrade --no-cache-dir pip wheel \
|
||||
&& python3 -m pip install --default-timeout=1000 --upgrade --no-cache-dir supervisor \
|
||||
&& python3 -m pip install --default-timeout=1000 --no-cache-dir -r ../requirements.txt \
|
||||
&& apt-get -y purge build-essential \
|
||||
&& apt-get -y autoremove --purge \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN set -eux \
|
||||
&& apt-get update \
|
||||
&& apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} ${BUILD_PACKAGES} \
|
||||
&& python3 -m pip install --no-cache-dir --upgrade wheel \
|
||||
&& echo "Installing qpdf" \
|
||||
&& apt-get install --yes --no-install-recommends ./libqpdf28_*.deb \
|
||||
&& apt-get install --yes --no-install-recommends ./qpdf_*.deb \
|
||||
&& echo "Installing pikepdf and dependencies wheel" \
|
||||
&& python3 -m pip install --no-cache-dir packaging*.whl \
|
||||
&& python3 -m pip install --no-cache-dir lxml*.whl \
|
||||
&& python3 -m pip install --no-cache-dir Pillow*.whl \
|
||||
&& python3 -m pip install --no-cache-dir pyparsing*.whl \
|
||||
&& python3 -m pip install --no-cache-dir pikepdf*.whl \
|
||||
&& python -m pip list \
|
||||
&& echo "Installing psycopg2 wheel" \
|
||||
&& python3 -m pip install --no-cache-dir psycopg2*.whl \
|
||||
&& python -m pip list \
|
||||
&& echo "Installing supervisor" \
|
||||
&& python3 -m pip install --default-timeout=1000 --upgrade --no-cache-dir supervisor \
|
||||
&& echo "Installing Python requirements" \
|
||||
&& python3 -m pip install --default-timeout=1000 --no-cache-dir -r ../requirements.txt \
|
||||
&& echo "Cleaning up image" \
|
||||
&& apt-get -y purge ${BUILD_PACKAGES} \
|
||||
&& apt-get -y autoremove --purge \
|
||||
&& apt-get clean --yes \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& rm -rf /tmp/* \
|
||||
&& rm -rf /var/tmp/* \
|
||||
&& rm -rf /var/cache/apt/archives/* \
|
||||
&& truncate -s 0 /var/log/*log
|
||||
|
||||
# setup docker-specific things
|
||||
COPY docker/ ./docker/
|
||||
|
||||
RUN cd docker \
|
||||
&& cp imagemagick-policy.xml /etc/ImageMagick-6/policy.xml \
|
||||
WORKDIR /usr/src/paperless/src/docker/
|
||||
|
||||
RUN set -eux \
|
||||
&& cp imagemagick-policy.xml /etc/ImageMagick-6/policy.xml \
|
||||
&& mkdir /var/log/supervisord /var/run/supervisord \
|
||||
&& cp supervisord.conf /etc/supervisord.conf \
|
||||
&& cp docker-entrypoint.sh /sbin/docker-entrypoint.sh \
|
||||
@ -42,17 +139,20 @@ RUN cd docker \
|
||||
&& cp docker-prepare.sh /sbin/docker-prepare.sh \
|
||||
&& chmod 755 /sbin/docker-prepare.sh \
|
||||
&& chmod +x install_management_commands.sh \
|
||||
&& ./install_management_commands.sh \
|
||||
&& cd .. \
|
||||
&& rm -rf docker/
|
||||
&& ./install_management_commands.sh
|
||||
|
||||
COPY gunicorn.conf.py ../
|
||||
WORKDIR /usr/src/paperless/
|
||||
|
||||
COPY gunicorn.conf.py .
|
||||
|
||||
WORKDIR /usr/src/paperless/src/
|
||||
|
||||
# copy app
|
||||
COPY --from=compile-frontend /src/src/ ./
|
||||
|
||||
# add users, setup scripts
|
||||
RUN addgroup --gid 1000 paperless \
|
||||
RUN set -eux \
|
||||
&& addgroup --gid 1000 paperless \
|
||||
&& useradd --uid 1000 --gid paperless --home-dir /usr/src/paperless paperless \
|
||||
&& chown -R paperless:paperless ../ \
|
||||
&& gosu paperless python3 manage.py collectstatic --clear --no-input \
|
||||
|
47
build-docker-image.sh
Executable file
47
build-docker-image.sh
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Helper script for building the Docker image locally.
|
||||
# Parses and provides the nessecary versions of other images to Docker
|
||||
# before passing in the rest of script args. A future enhancement
|
||||
# would be to combine this with the CI script
|
||||
|
||||
# First Argument: The Dockerfile to build
|
||||
# Other Arguments: Additional arguments to docker build
|
||||
|
||||
# Example Usage:
|
||||
# ./build-docker-image.sh Dockerfile -t paperless-ngx:my-awesome-feature
|
||||
# ./build-docker-image.sh docker-builders/Dockerfile.qpdf -t paperless-ngx-build-qpdf:x.y.z
|
||||
|
||||
set -eux
|
||||
|
||||
if ! command -v jq; then
|
||||
echo "jq required"
|
||||
exit 1
|
||||
elif [ ! -f "$1" ]; then
|
||||
echo "$1 is not a file, please provide the Dockerfile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse what we can from Pipfile.lock
|
||||
pikepdf_version=$(jq ".default.pikepdf.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g')
|
||||
psycopg2_version=$(jq ".default.psycopg2.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g')
|
||||
# Read this from the other config file
|
||||
qpdf_version=$(jq ".qpdf.version" .build-config.json | sed 's/"//g')
|
||||
jbig2enc_version=$(jq ".jbig2enc.version" .build-config.json | sed 's/"//g')
|
||||
# Get the branch name
|
||||
frontend_version=$(git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# Get Git tags for building
|
||||
# psycopg2 uses X_Y_Z git tags
|
||||
psycopg2_git_tag=${psycopg2_version//./_}
|
||||
# pikepdf uses vX.Y.Z
|
||||
pikepdf_git_tag="v${pikepdf_version}"
|
||||
|
||||
docker build --file "$1" \
|
||||
--build-arg JBIG2ENC_VERSION="${jbig2enc_version}" \
|
||||
--build-arg QPDF_VERSION="${qpdf_version}" \
|
||||
--build-arg PIKEPDF_VERSION="${pikepdf_version}" \
|
||||
--build-arg PIKEPDF_GIT_TAG="${pikepdf_git_tag}" \
|
||||
--build-arg PSYCOPG2_VERSION="${psycopg2_version}" \
|
||||
--build-arg PSYCOPG2_GIT_TAG="${psycopg2_git_tag}" \
|
||||
--build-arg FRONTEND_VERSION="${frontend_version}" "${@:2}" .
|
14
docker-builders/Dockerfile.frontend
Normal file
14
docker-builders/Dockerfile.frontend
Normal file
@ -0,0 +1,14 @@
|
||||
# This Dockerfile compiles the frontend
|
||||
# Inputs: None
|
||||
|
||||
FROM node:16-bullseye-slim AS compile-frontend
|
||||
|
||||
COPY ./src /src/src
|
||||
COPY ./src-ui /src/src-ui
|
||||
|
||||
WORKDIR /src/src-ui
|
||||
RUN set -eux \
|
||||
&& npm update npm -g \
|
||||
&& npm ci --no-optional
|
||||
RUN set -eux \
|
||||
&& ./node_modules/.bin/ng build --configuration production
|
39
docker-builders/Dockerfile.jbig2enc
Normal file
39
docker-builders/Dockerfile.jbig2enc
Normal file
@ -0,0 +1,39 @@
|
||||
# This Dockerfile compiles the jbig2enc library
|
||||
# Inputs:
|
||||
# - JBIG2ENC_VERSION - the Git tag to checkout and build
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
LABEL org.opencontainers.image.description="A intermediate image with jbig2enc built"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG BUILD_PACKAGES="\
|
||||
build-essential \
|
||||
automake \
|
||||
libtool \
|
||||
libleptonica-dev \
|
||||
zlib1g-dev \
|
||||
git \
|
||||
ca-certificates"
|
||||
|
||||
WORKDIR /usr/src/jbig2enc
|
||||
|
||||
# As this is an base image for a multi-stage final image
|
||||
# the added size of the install is basically irrelevant
|
||||
RUN apt-get update --quiet \
|
||||
&& apt-get install --yes --quiet --no-install-recommends ${BUILD_PACKAGES} \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Layers after this point change according to required version
|
||||
# For better caching, seperate the basic installs from
|
||||
# the building
|
||||
|
||||
ARG JBIG2ENC_VERSION
|
||||
|
||||
RUN set -eux \
|
||||
&& git clone --quiet --branch $JBIG2ENC_VERSION https://github.com/agl/jbig2enc .
|
||||
RUN set -eux \
|
||||
&& ./autogen.sh
|
||||
RUN set -eux \
|
||||
&& ./configure && make
|
69
docker-builders/Dockerfile.pikepdf
Normal file
69
docker-builders/Dockerfile.pikepdf
Normal file
@ -0,0 +1,69 @@
|
||||
# This Dockerfile builds the pikepdf wheel
|
||||
# Inputs:
|
||||
# - REPO - Docker repository to pull qpdf from
|
||||
# - QPDF_VERSION - The image qpdf version to copy .deb files from
|
||||
# - PIKEPDF_GIT_TAG - The Git tag to clone and build from
|
||||
# - PIKEPDF_VERSION - Used to force the built pikepdf version to match
|
||||
|
||||
# Default to pulling from the main repo registry when manually building
|
||||
ARG REPO="paperless-ngx/paperless-ngx"
|
||||
|
||||
ARG QPDF_VERSION
|
||||
FROM ghcr.io/${REPO}/builder/qpdf:${QPDF_VERSION} as qpdf-builder
|
||||
|
||||
# This does nothing, except provide a name for a copy below
|
||||
|
||||
FROM python:3.9-slim-bullseye
|
||||
|
||||
LABEL org.opencontainers.image.description="A intermediate image with pikepdf wheel built"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG BUILD_PACKAGES="\
|
||||
build-essential \
|
||||
git \
|
||||
libjpeg62-turbo-dev \
|
||||
zlib1g-dev \
|
||||
libgnutls28-dev \
|
||||
libxml2-dev \
|
||||
libxslt1-dev \
|
||||
python3-dev \
|
||||
python3-pip"
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
COPY --from=qpdf-builder /usr/src/qpdf/*.deb ./
|
||||
|
||||
# As this is an base image for a multi-stage final image
|
||||
# the added size of the install is basically irrelevant
|
||||
|
||||
RUN set -eux \
|
||||
&& apt-get update --quiet \
|
||||
&& apt-get install --yes --quiet --no-install-recommends $BUILD_PACKAGES \
|
||||
&& dpkg --install libqpdf28_*.deb \
|
||||
&& dpkg --install libqpdf-dev_*.deb \
|
||||
&& python3 -m pip install --no-cache-dir --upgrade pip wheel pybind11 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Layers after this point change according to required version
|
||||
# For better caching, seperate the basic installs from
|
||||
# the building
|
||||
|
||||
ARG PIKEPDF_GIT_TAG
|
||||
ARG PIKEPDF_VERSION
|
||||
|
||||
RUN set -eux \
|
||||
&& echo "building pikepdf wheel" \
|
||||
# Note the v in the tag name here
|
||||
&& git clone --quiet --depth 1 --branch "${PIKEPDF_GIT_TAG}" https://github.com/pikepdf/pikepdf.git \
|
||||
&& cd pikepdf \
|
||||
# pikepdf seems to specifciy either a next version when built OR
|
||||
# a post release tag.
|
||||
# In either case, this won't match what we want from requirements.txt
|
||||
# Directly modify the setup.py to set the version we just checked out of Git
|
||||
&& sed -i "s/use_scm_version=True/version=\"${PIKEPDF_VERSION}\"/g" setup.py \
|
||||
# https://github.com/pikepdf/pikepdf/issues/323
|
||||
&& rm pyproject.toml \
|
||||
&& mkdir wheels \
|
||||
&& python3 -m pip wheel . --wheel-dir wheels \
|
||||
&& ls -ahl wheels
|
44
docker-builders/Dockerfile.psycopg2
Normal file
44
docker-builders/Dockerfile.psycopg2
Normal file
@ -0,0 +1,44 @@
|
||||
# This Dockerfile builds the psycopg2 wheel
|
||||
# Inputs:
|
||||
# - PSYCOPG2_GIT_TAG - The Git tag to clone and build from
|
||||
# - PSYCOPG2_VERSION - Unused, kept for future possible usage
|
||||
|
||||
FROM python:3.9-slim-bullseye
|
||||
|
||||
LABEL org.opencontainers.image.description="A intermediate image with psycopg2 wheel built"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG BUILD_PACKAGES="\
|
||||
build-essential \
|
||||
git \
|
||||
libpq-dev \
|
||||
python3-dev \
|
||||
python3-pip"
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
# As this is an base image for a multi-stage final image
|
||||
# the added size of the install is basically irrelevant
|
||||
|
||||
RUN set -eux \
|
||||
&& apt-get update --quiet \
|
||||
&& apt-get install --yes --quiet --no-install-recommends $BUILD_PACKAGES \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& python3 -m pip install --no-cache-dir --upgrade pip wheel
|
||||
|
||||
# Layers after this point change according to required version
|
||||
# For better caching, seperate the basic installs from
|
||||
# the building
|
||||
|
||||
ARG PSYCOPG2_GIT_TAG
|
||||
ARG PSYCOPG2_VERSION
|
||||
|
||||
RUN set -eux \
|
||||
&& echo "Building psycopg2 wheel" \
|
||||
&& cd /usr/src \
|
||||
&& git clone --quiet --depth 1 --branch ${PSYCOPG2_GIT_TAG} https://github.com/psycopg/psycopg2.git \
|
||||
&& cd psycopg2 \
|
||||
&& mkdir wheels \
|
||||
&& python3 -m pip wheel . --wheel-dir wheels \
|
||||
&& ls -ahl wheels/
|
52
docker-builders/Dockerfile.qpdf
Normal file
52
docker-builders/Dockerfile.qpdf
Normal file
@ -0,0 +1,52 @@
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
LABEL org.opencontainers.image.description="A intermediate image with qpdf built"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG BUILD_PACKAGES="\
|
||||
build-essential \
|
||||
debhelper \
|
||||
debian-keyring \
|
||||
devscripts \
|
||||
equivs \
|
||||
libtool \
|
||||
libjpeg62-turbo-dev \
|
||||
libgnutls28-dev \
|
||||
packaging-dev \
|
||||
zlib1g-dev"
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
# As this is an base image for a multi-stage final image
|
||||
# the added size of the install is basically irrelevant
|
||||
|
||||
RUN set -eux \
|
||||
&& apt-get update --quiet \
|
||||
&& apt-get install --yes --quiet --no-install-recommends $BUILD_PACKAGES \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Layers after this point change according to required version
|
||||
# For better caching, seperate the basic installs from
|
||||
# the building
|
||||
|
||||
# This must match to pikepdf's minimum at least
|
||||
ARG QPDF_VERSION
|
||||
|
||||
# In order to get the required version of qpdf, it is backported from bookwork
|
||||
# and then built from source
|
||||
RUN set -eux \
|
||||
&& echo "Building qpdf" \
|
||||
&& echo "deb-src http://deb.debian.org/debian/ bookworm main" > /etc/apt/sources.list.d/bookworm-src.list \
|
||||
&& apt-get update \
|
||||
&& mkdir qpdf \
|
||||
&& cd qpdf \
|
||||
&& apt-get source --yes --quiet qpdf=${QPDF_VERSION}-1/bookworm \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& cd qpdf-$QPDF_VERSION \
|
||||
# We don't need to build the tests (also don't run them)
|
||||
&& rm -rf libtests \
|
||||
&& DEBEMAIL=hello@paperless-ngx.com debchange --bpo \
|
||||
&& export DEB_BUILD_OPTIONS="terse nocheck nodoc parallel=2" \
|
||||
&& dpkg-buildpackage --build=binary --unsigned-source --unsigned-changes \
|
||||
&& ls -ahl ../*.deb
|
102
docker-builders/get-build-json.py
Executable file
102
docker-builders/get-build-json.py
Executable file
@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This is a helper script for the mutli-stage Docker image builder.
|
||||
It provides a single point of configuration for package version control.
|
||||
The output JSON object is used by the CI workflow to determine what versions
|
||||
to build and pull into the final Docker image.
|
||||
|
||||
Python package information is obtained from the Pipfile.lock. As this is
|
||||
kept updated by dependabot, it usually will need no further configuration.
|
||||
The sole exception currently is pikepdf, which has a dependency on qpdf,
|
||||
and is configured here to use the latest version of qpdf built by the workflow.
|
||||
|
||||
Other package version information is configured directly below, generally by
|
||||
setting the version and Git information, if any.
|
||||
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
|
||||
def _get_image_tag(
|
||||
repo_name: str,
|
||||
pkg_name: str,
|
||||
pkg_version: str,
|
||||
) -> str:
|
||||
return f"ghcr.io/{repo_name}/builder/{pkg_name}:{pkg_version}"
|
||||
|
||||
|
||||
def _main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate a JSON object of information required to build the given package, based on the Pipfile.lock",
|
||||
)
|
||||
parser.add_argument(
|
||||
"package",
|
||||
help="The name of the package to generate JSON for",
|
||||
)
|
||||
|
||||
PIPFILE_LOCK_PATH: Final[Path] = Path("Pipfile.lock")
|
||||
BUILD_CONFIG_PATH: Final[Path] = Path(".build-config.json")
|
||||
|
||||
# Read the main config file
|
||||
build_json: Final = json.loads(BUILD_CONFIG_PATH.read_text())
|
||||
|
||||
# Read Pipfile.lock file
|
||||
pipfile_data: Final = json.loads(PIPFILE_LOCK_PATH.read_text())
|
||||
|
||||
args: Final = parser.parse_args()
|
||||
|
||||
repo_name: Final[str] = os.environ["GITHUB_REPOSITORY"]
|
||||
|
||||
# Default output values
|
||||
version = None
|
||||
git_tag = None
|
||||
extra_config = {}
|
||||
|
||||
if args.package == "frontend":
|
||||
# Version is just the branch or tag name
|
||||
version = os.environ["GITHUB_REF_NAME"]
|
||||
elif args.package in pipfile_data["default"]:
|
||||
# Read the version from Pipfile.lock
|
||||
pkg_data = pipfile_data["default"][args.package]
|
||||
pkg_version = pkg_data["version"].split("==")[-1]
|
||||
version = pkg_version
|
||||
|
||||
# Based on the package, generate the expected Git tag name
|
||||
if args.package == "pikepdf":
|
||||
git_tag = f"v{pkg_version}"
|
||||
elif args.package == "psycopg2":
|
||||
git_tag = pkg_version.replace(".", "_")
|
||||
|
||||
# Any extra/special values needed
|
||||
if args.package == "pikepdf":
|
||||
extra_config["qpdf_version"] = build_json["qpdf"]["version"]
|
||||
|
||||
elif args.package in build_json:
|
||||
version = build_json[args.package]["version"]
|
||||
|
||||
if "git_tag" in build_json[args.package]:
|
||||
git_tag = build_json[args.package]["git_tag"]
|
||||
else:
|
||||
raise NotImplementedError(args.package)
|
||||
|
||||
# The JSON object we'll output
|
||||
output = {
|
||||
"name": args.package,
|
||||
"version": version,
|
||||
"git_tag": git_tag,
|
||||
"image_tag": _get_image_tag(repo_name, args.package, version),
|
||||
}
|
||||
|
||||
# Add anything special a package may need
|
||||
output.update(extra_config)
|
||||
|
||||
# Output the JSON info to stdout
|
||||
print(json.dumps(output))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_main()
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
wait_for_postgres() {
|
||||
attempt_num=1
|
||||
max_attempts=5
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
for command in document_archiver document_exporter document_importer mail_fetcher document_create_classifier document_index document_renamer document_retagger document_thumbnails document_sanity_checker manage_superuser;
|
||||
do
|
||||
echo "installing $command..."
|
||||
|
@ -1,10 +1,10 @@
|
||||
FROM python:3.5.1
|
||||
|
||||
# Install Sphinx and Pygments
|
||||
RUN pip install Sphinx Pygments
|
||||
RUN pip install --no-cache-dir Sphinx Pygments \
|
||||
# Setup directories, copy data
|
||||
&& mkdir /build
|
||||
|
||||
# Setup directories, copy data
|
||||
RUN mkdir /build
|
||||
COPY . /build
|
||||
WORKDIR /build/docs
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user