diff --git a/.github/workflows/generate_release.yaml b/.github/workflows/generate_release.yaml new file mode 100644 index 00000000..df932c1c --- /dev/null +++ b/.github/workflows/generate_release.yaml @@ -0,0 +1,123 @@ +name: Generate e-books + +on: + push: + tags: + - 'v*.*' # Create a release only when a new tag matching v*.* is pushed. + # To also create a release for each push to the main branch, uncomment the following 2 lines: + # branches: + # - master + pull_request: + branches: + - master + workflow_dispatch: {} # For manual runs. + +jobs: + release-ebooks: + # Run for tag pushes (and optionally for branch pushes if the "branches" node is uncommented above). + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Export all supported book formats from the Docker container + run: | + make run + make export + + - name: Copy generated files to host system + run: | + make cp + mkdir -p artifacts/ + mv "Linux Inside - 0xAX.epub" \ + "Linux Inside - 0xAX.mobi" \ + "Linux Inside - 0xAX.pdf" \ + "Linux Inside - 0xAX (A5).pdf" \ + artifacts/ + cp LICENSE artifacts/ + + - name: Prepare release metadata + # Use tag name when running on a tag, otherwise fall back to the short commit hash. + id: meta + env: + GITHUB_REF_TYPE: ${{ github.ref_type }} + GITHUB_REF_NAME: ${{ github.ref_name }} + run: | + DATE_US="$(date -u '+%m/%d/%Y %H:%M')" + if [ "${GITHUB_REF_TYPE}" = "tag" ] && [ -n "${GITHUB_REF_NAME}" ]; then + LABEL="${GITHUB_REF_NAME}" + else + LABEL="$(git rev-parse --short HEAD)" + fi + echo "release_name=${DATE_US} (${LABEL})" >> "$GITHUB_OUTPUT" + echo "tag_name=${LABEL}" >> "$GITHUB_OUTPUT" + + - name: Create GitHub release + uses: softprops/action-gh-release@v2 + with: + files: artifacts/* + name: ${{ steps.meta.outputs.release_name }} + tag_name: ${{ steps.meta.outputs.tag_name }} + target_commitish: ${{ github.sha }} + generate_release_notes: true + fail_on_unmatched_files: true + + build-for-pr: + # For every PR, build the same artifacts and make them accessible from the PR. + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Export all supported book formats from the Docker container + run: | + make run + make export + + - name: Copy generated files to host system + run: | + make cp + mkdir -p artifacts/ + mv "Linux Inside - 0xAX.epub" \ + "Linux Inside - 0xAX.mobi" \ + "Linux Inside - 0xAX.pdf" \ + "Linux Inside - 0xAX (A5).pdf" \ + artifacts/ + + - name: Upload PR artifacts + uses: actions/upload-artifact@v4 + with: + name: ebooks-${{ github.sha }} + path: artifacts/* + if-no-files-found: error + # Change the retention period here if necessary. + retention-days: 90 + + - name: Add a comment with a link to the generated artifacts. + # For forked PRs the token is read-only; skip commenting to avoid failures. + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }} + uses: actions/github-script@v7 + env: + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + with: + script: | + const body = [ + `E-books generated for this pull request available at: ${process.env.RUN_URL}` + ].join('\n'); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body + }); \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 48b772b3..e29d7c34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,28 @@ FROM lrx0014/gitbook:3.2.3 COPY ./ /srv/gitbook/ -EXPOSE 4000 \ No newline at end of file +EXPOSE 4000 + +# Update sources.list for Debian Jessie. +RUN rm /etc/apt/sources.list +RUN echo "deb http://archive.debian.org/debian-security jessie/updates main" >> /etc/apt/sources.list.d/jessie.list +RUN echo "deb http://archive.debian.org/debian jessie main" >> /etc/apt/sources.list.d/jessie.list +RUN apt update +RUN apt install -y --force-yes calibre bzip2 +RUN npm install svgexport@0.3.0 -g + +# Install CommandBox (https://commandbox.ortusbooks.com/setup/installation). +# Requires OpenJDK 11 but only version 7 is available from Debian Jessie repositories. +# Run that on a more up-to-date system. +#RUN apt install -y libappindicator3-dev openjdk-11-jdk +#RUN curl -fsSl https://downloads.ortussolutions.com/debs/gpg | gpg --dearmor | tee /usr/share/keyrings/ortussolutions.gpg > /dev/null +#RUN echo "deb [signed-by=/usr/share/keyrings/ortussolutions.gpg] https://downloads.ortussolutions.com/debs/noarch /" | tee /etc/apt/sources.list.d/commandbox.list +#RUN apt-get update && apt-get install -y apt-transport-https commandbox + +# Install gitbook-exporter into the CommandBox. +#RUN box install gitbook-exporter + +# Run CommandBox shell with gitbook command available. (https://www.forgebox.io/view/gitbook-exporter) +# Examples: +#RUN gitbook pdf +#RUN gitbook epub + diff --git a/Makefile b/Makefile index f05b586e..4445148c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -### HELP +### HELP # test .PHONY: help help: ## Print help @@ -9,13 +9,56 @@ help: ## Print help .PHONY: run run: image ## docker run ... (docker stop linux-insides-book 2>&1) > /dev/null || true - docker run --detach --rm -p 4000:4000 --name linux-insides-book --hostname linux-insides-book linux-insides-book + docker run --detach -p 4000:4000 --name linux-insides-book --hostname linux-insides-book linux-insides-book + +.PHONY: start +start: ## start the docker container ... + docker start linux-insides-book .PHONY: image image: ## docker image build ... docker image build --rm --squash --label linux-insides --tag linux-insides-book:latest -f Dockerfile . 2> /dev/null || \ docker image build --rm --label linux-insides --tag linux-insides-book:latest -f Dockerfile . +.PHONY: sh +sh: ## run interactive shell inside an already running docker container ... + docker exec -it linux-insides-book sh + +.PHONY: rm +rm: ## remove the docker container ... + (docker stop linux-insides-book 2>&1) > /dev/null || true + (docker rm linux-insides-book 2>&1) > /dev/null || true + +.PHONY: logs +logs: ## gather logs from the docker container ... + docker logs linux-insides-book + +.PHONY: export +export: ## run e-book generation inside an already running docker container ... + docker exec linux-insides-book /bin/bash -c " \ + gitbook epub; \ + gitbook mobi; \ + gitbook pdf; \ + mv book.pdf book-A4.pdf; \ + mv book-A5.json book.json; \ + gitbook pdf; \ + mv book.pdf book-A5.pdf; \ + mv book-A4.pdf book.pdf" + +.PHONY: cp +cp: ## copy all exported e-book formats to current working directory ... + docker cp linux-insides-book:/srv/gitbook/book.epub "Linux Inside - 0xAX.epub" + docker cp linux-insides-book:/srv/gitbook/book.mobi "Linux Inside - 0xAX.mobi" + docker cp linux-insides-book:/srv/gitbook/book.pdf "Linux Inside - 0xAX.pdf" + docker cp linux-insides-book:/srv/gitbook/book-A5.pdf "Linux Inside - 0xAX (A5).pdf" + +.PHONY: clean +clean: ## remove all exported e-book files ... + rm "Linux Inside - 0xAX.epub" \ + "Linux Inside - 0xAX.mobi" \ + "Linux Inside - 0xAX.pdf" \ + "Linux Inside - 0xAX (A5).pdf" + ### LAUNCH BROWSER .PHONY: browse diff --git a/book-A5.json b/book-A5.json new file mode 100644 index 00000000..2cda7624 --- /dev/null +++ b/book-A5.json @@ -0,0 +1,14 @@ +{ + "title": "Linux Insides", + "author" : "0xAX", + "pdf": { + "paperSize": "a5", + "margin": + { + "top": 48, + "bottom": 48, + "right": 28, + "left": 28 + } + } +} diff --git a/book.json b/book.json index 2cda7624..245a7ec9 100644 --- a/book.json +++ b/book.json @@ -1,14 +1,4 @@ { "title": "Linux Insides", - "author" : "0xAX", - "pdf": { - "paperSize": "a5", - "margin": - { - "top": 48, - "bottom": 48, - "right": 28, - "left": 28 - } - } + "author" : "0xAX" }