From f171572ff70ec897d0821328583c44fc2539926e Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Sat, 3 Jun 2023 06:29:49 -0500 Subject: [PATCH] Convert to a GitHub action --- .github/workflows/ci.yaml | 114 +++++++++++++++++++ Dockerfile | 75 +++++++------ Dockerfile_kicad-auto | 203 --------------------------------- Makefile | 60 ---------- README.md | 161 +++++++++++++------------- action.yml | 166 +++++++++++++++++++++++++++ entrypoint.sh | 81 ++++++++++++++ kiri | 230 -------------------------------------- 8 files changed, 479 insertions(+), 611 deletions(-) create mode 100644 .github/workflows/ci.yaml delete mode 100644 Dockerfile_kicad-auto delete mode 100644 Makefile create mode 100644 action.yml create mode 100644 entrypoint.sh delete mode 100755 kiri diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..541b7a5 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,114 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - 'main' + paths: + - 'Dockerfile' + - 'entrypoint.sh' + - 'config/**' + - '.github/workflows/ci.yaml' + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Log in to GHCR + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set tag name + id: tag_name + run: | + if [ "${{ github.ref }}" == "refs/heads/main" ]; then + echo "tag=latest" >> $GITHUB_OUTPUT + else + echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + fi + - name: Extract full version from tag, ie refs/tags/v1.2.3 -> v1.2.3 + id: full_version + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + run: | + echo "full_version=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + # Make sure that the line in `action.yml` similar to docker://ghcr.io/usa-reddragon/kiri:v1.2.3 is updated + - name: Update action.yml + if: startsWith(github.ref, 'refs/tags/v') + run: | + sed -i "s/docker:\/\/ghcr.io\/usa-reddragon\/kiri:v[0-9]\+\.[0-9]\+\.[0-9]\+/docker:\/\/ghcr.io\/usa-reddragon\/kiri:${{ steps.full_version.outputs.full_version }}/g" action.yml + - name: Setup git config + if: startsWith(github.ref, 'refs/tags/v') + run: | + git config --local user.email "${GITHUB_ACTOR}@users.noreply.github.com" + git config --local user.name "${GITHUB_ACTOR}" + - name: Fail if action.yml was not updated + if: startsWith(github.ref, 'refs/tags/v') + run: | + if [ -n "$(git status --porcelain action.yml)" ]; then + echo "Failing because action.yml was not updated with the new version" + git add action.yml + git diff --staged action.yml + exit 1 + fi + - name: Build and push + uses: docker/build-push-action@v4 + with: + push: true + tags: ghcr.io/usa-reddragon/kiri:${{ steps.tag_name.outputs.tag }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Extract minor version from tag, ie v1.2.3 -> v1.2 + id: minor_version + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + run: | + echo "minor_version=${GITHUB_REF#refs/*/}" | sed 's/\.[^.]*$//' >> $GITHUB_OUTPUT + - name: Extract major version from tag, ie v1.2.3 -> v1 + id: major_version + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + run: | + echo "major_version=${GITHUB_REF#refs/*/}" | sed 's/\.[^.]*$//' | sed 's/\.[^.]*$//' >> $GITHUB_OUTPUT + - name: Build and push minor version + uses: docker/build-push-action@v4 + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + with: + push: true + tags: ghcr.io/usa-reddragon/kiri:${{ steps.minor_version.outputs.minor_version }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Build and push major version + uses: docker/build-push-action@v4 + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + with: + push: true + tags: ghcr.io/usa-reddragon/kiri:${{ steps.major_version.outputs.major_version }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Re-tag minor and major version + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release' + run: | + git tag -d ${{ steps.minor_version.outputs.minor_version }} || true + git tag -d ${{ steps.major_version.outputs.major_version }} || true + git push origin :refs/tags/${{ steps.minor_version.outputs.minor_version }} || true + git push origin :refs/tags/${{ steps.major_version.outputs.major_version }} || true + git tag ${{ steps.minor_version.outputs.minor_version }} ${{ steps.full_version.outputs.full_version }} + git tag ${{ steps.major_version.outputs.major_version }} ${{ steps.full_version.outputs.full_version }} + git push origin ${{ steps.minor_version.outputs.minor_version }} + git push origin ${{ steps.major_version.outputs.major_version }} + - name: Create Release + id: create_release + if: startsWith(github.ref, 'refs/tags/v') + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + with: + tag_name: ${{ steps.full_version.outputs.full_version }} + release_name: Release ${{ steps.full_version.outputs.full_version }} + draft: false + prerelease: false diff --git a/Dockerfile b/Dockerfile index d118ebc..6ba951b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,20 +2,20 @@ # Latest stable version of Ubuntu, of course FROM ubuntu:22.04 -LABEL org.opencontainers.image.authors "Leandro Heck " +LABEL org.opencontainers.image.authors "Leandro Heck , Jacob McSwain " LABEL org.opencontainers.image.description "Kicad 7 and KiRI" -LABEL org.opencontainers.image.url "https://hub.docker.com/r/leoheck/kiri/main" -LABEL org.opencontainers.image.documentation "https://github.com/leoheck/kiri-docker" +LABEL org.opencontainers.image.url "https://github.com/USA-RedDragon/kiri-github-action/pkgs/container/kiri" +LABEL org.opencontainers.image.documentation "https://github.com/USA-RedDragon/kiri-github-action" +LABEL org.opencontainers.image.source "https://github.com/USA-RedDragon/kiri-github-action" ARG DEBIAN_FRONTEND noninteractive ARG DEBCONF_NOWARNINGS="yes" -ARG TERM 'dumb' +ENV TERM 'dumb' RUN apt-get update RUN apt-get install -y \ sudo \ git \ - zsh \ curl \ coreutils \ software-properties-common \ @@ -49,18 +49,19 @@ RUN apt-get install --no-install-recommends -y kicad && \ rm -rf /var/tmp/* # Create user -RUN useradd -rm -d "/home/kiri" -s "/usr/bin/zsh" -g root -G sudo -u 1000 kiri -p kiri +RUN useradd -rm -d "/home/github" -s "$(which bash)" -G sudo -u 1001 -U github # Run sudo without password -RUN echo "kiri ALL=(ALL) NOPASSWD:ALL" | tee sudo -a "/etc/sudoers" +RUN echo "github ALL=(ALL) NOPASSWD:ALL" | tee sudo -a "/etc/sudoers" # Change current user -USER kiri -WORKDIR "/home/kiri" -ENV USER kiri +USER github +WORKDIR "/home/github" +ENV USER github +ENV HOME /home/github ENV DISPLAY :0 -ENV PATH "${PATH}:/home/kiri/.local/bin" +ENV PATH "${PATH}:/home/github/.local/bin" # Python dependencies RUN yes | pip3 install \ @@ -89,14 +90,11 @@ RUN yes | opam init --disable-sandboxing && \ rm -rf ~/.opam/download-cache ;\ rm -rf ~/.opam/repo/* -# Oh-my-zsh, please -RUN zsh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" || true - # Install kiri, kidiff and plotgitsch -ADD https://api.github.com/repos/leoheck/kiri/git/refs/heads/main kiri_version.json -ENV KIRI_HOME "/home/kiri/.local/share/" -RUN git clone --recurse-submodules -j8 https://github.com/leoheck/kiri.git "${KIRI_HOME}/kiri" -RUN cd "${KIRI_HOME}/kiri/submodules/plotkicadsch" && \ +ADD https://api.github.com/repos/USA-RedDragon/kiri/git/refs/heads/main kiri_version.json +ENV KIRI_HOME "/home/github/.local/share/kiri" +RUN git clone --recurse-submodules -j8 https://github.com/USA-RedDragon/kiri.git "${KIRI_HOME}" +RUN cd "${KIRI_HOME}/submodules/plotkicadsch" && \ opam pin add -y kicadsch . && \ opam pin add -y plotkicadsch . && \ opam install -y plotkicadsch; \ @@ -104,23 +102,7 @@ RUN cd "${KIRI_HOME}/kiri/submodules/plotkicadsch" && \ rm -rf ~/.opam/download-cache ;\ rm -rf ~/.opam/repo/* -# Opam configuration -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# OPAM configuration' | tee -a "${HOME}/.zshrc" -RUN echo "test -r /home/kiri/.opam/opam-init/init.sh && . /home/kiri/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true" | tee -a "${HOME}/.zshrc" - -# KiRI environment -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# KIRI Environment' | tee -a "${HOME}/.zshrc" -RUN echo 'export KIRI_HOME=${HOME}/.local/share/kiri' | tee -a "${HOME}/.zshrc" -RUN echo 'export PATH=${KIRI_HOME}/submodules/KiCad-Diff/bin:${PATH}' | tee -a "${HOME}/.zshrc" -RUN echo 'export PATH=${KIRI_HOME}/bin:${PATH}' | tee -a "${HOME}/.zshrc" - -# Custom commands -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# Custom Commands' | tee -a "${HOME}/.zshrc" -RUN echo 'function ip() { awk "/32 host/ { print f } {f=\$2}" /proc/net/fib_trie | sort | uniq | grep -v 127.0.0.1 | head -n1 }' | tee -a "${HOME}/.zshrc" -RUN echo 'alias kiri="kiri -i \$(ip)"' | tee -a "${HOME}/.zshrc" +ENV PATH "${KIRI_HOME}/bin:${KIRI_HOME}/submodules/KiCad-Diff/bin:${PATH}" # Clean unnecessary stuff RUN sudo apt-get purge -y \ @@ -138,5 +120,24 @@ RUN sudo rm -rf \ /usr/share/man/* # Initialize Kicad config files to skip default popups of setup -COPY config "/home/kiri/.config" -RUN sudo chown -R kiri "/home/kiri/.config" +COPY config "/home/github/.config" +RUN sudo chown -R github:github "/home/github/.config" + +COPY entrypoint.sh /entrypoint.sh +RUN sudo chmod a+rx /entrypoint.sh + +# GitHub Actions environment variables +ENV KIRI_PROJECT_FILE "" +ENV KIRI_OUTPUT_DIR "" +ENV KIRI_REMOVE "" +ENV KIRI_ARCHIVE "" +ENV KIRI_PCB_PAGE_FRAME "" +ENV KIRI_FORCE_LAYOUT_VIEW "" +ENV KIRI_SKIP_KICAD6_SCHEMATICS "" +ENV KIRI_SKIP_CACHE "" +ENV KIRI_OLDER "" +ENV KIRI_NEWER "" +ENV KIRI_LAST "" +ENV KIRI_ALL "" + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/Dockerfile_kicad-auto b/Dockerfile_kicad-auto deleted file mode 100644 index 42d6b0a..0000000 --- a/Dockerfile_kicad-auto +++ /dev/null @@ -1,203 +0,0 @@ - -# We are going to use the latest version of ubuntu, of course -FROM ubuntu:22.04 - -LABEL org.opencontainers.image.authors "Leandor S. Heck " -LABEL org.opencontainers.image.description "Kicad 6 with KiRI (Kicad Revision Inspector" -LABEL org.opencontainers.image.url "https://hub.docker.com/r/leoheck/kiri/tags" -LABEL org.opencontainers.image.documentation "https://github.com/leoheck/kiri-docker" - -ARG DEBIAN_FRONTEND noninteractive -ARG DEBCONF_NOWARNINGS="yes" -ARG TERM 'dumb' - -RUN apt-get update -RUN apt-get install -y \ - sudo \ - git \ - zsh \ - curl \ - coreutils \ - software-properties-common \ - x11-utils \ - x11-xkb-utils \ - xvfb \ - opam \ - build-essential \ - pkg-config \ - libgmp-dev \ - util-linux \ - python-is-python3 \ - python3-pip \ - dos2unix \ - librsvg2-bin \ - imagemagick \ - xdotool \ - rename \ - bsdmainutils ;\ - apt-get clean ;\ - rm -rf /var/lib/apt/lists/* ;\ - rm -rf /var/tmp/* - -# install latest kicad 6.0.* -RUN add-apt-repository -y ppa:kicad/kicad-6.0-releases -RUN apt-get install --no-install-recommends -y kicad && \ - apt-get purge -y \ - software-properties-common ;\ - apt-get clean ;\ - rm -rf /var/lib/apt/lists/* ;\ - rm -rf /var/tmp/* - -# create user -RUN useradd -rm -d "/home/kiri" -s "/usr/bin/zsh" -g root -G sudo -u 1000 kiri -p kiri - -# run sudo without password -RUN echo "kiri ALL=(ALL) NOPASSWD:ALL" | tee sudo -a "/etc/sudoers" - -# change user -USER kiri -WORKDIR "/home/kiri" -ENV USER kiri -ENV DISPLAY :0 - -ENV PATH "${PATH}:/home/kiri/.local/bin" - -# python dependencies -RUN yes | pip3 install \ - "pillow>8.2.0" \ - "six>=1.15.0" \ - "python_dateutil>=2.8.1" \ - "pytz>=2021.1" \ - "pathlib>=1.0.1" && \ - pip3 cache purge - -# opam dependencies -RUN yes | opam init --disable-sandboxing && \ - opam switch create 4.10.2 && \ - eval "$(opam env)" && \ - opam update && \ - opam install -y \ - digestif \ - lwt \ - lwt_ppx \ - cmdliner \ - base64 \ - sha \ - tyxml \ - git-unix ;\ - opam clean -a -c -s --logs -r ;\ - rm -rf ~/.opam/download-cache ;\ - rm -rf ~/.opam/repo/* - -# oh-my-zsh, please -RUN zsh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" || true - -# install kiri, kidiff and plotgitsch -ADD https://api.github.com/repos/leoheck/kiri/git/refs/heads/main kiri_version.json -ENV KIRI_HOME "/home/kiri/.local/share/" -RUN git clone --recurse-submodules -j8 https://github.com/leoheck/kiri.git "${KIRI_HOME}/kiri" -RUN cd "${KIRI_HOME}/kiri/submodules/plotkicadsch" && \ - opam pin add -y kicadsch . && \ - opam pin add -y plotkicadsch . && \ - opam install -y plotkicadsch; \ - opam clean -a -c -s --logs -r ;\ - rm -rf ~/.opam/download-cache ;\ - rm -rf ~/.opam/repo/* - -# opam configuration -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# OPAM configuration' | tee -a "${HOME}/.zshrc" -RUN echo "test -r /home/kiri/.opam/opam-init/init.sh && . /home/kiri/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true" | tee -a "${HOME}/.zshrc" - -# kiri environment -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# KIRI Environment' | tee -a "${HOME}/.zshrc" -RUN echo 'export KIRI_HOME=${HOME}/.local/share/kiri' | tee -a "${HOME}/.zshrc" -RUN echo 'export PATH=${KIRI_HOME}/submodules/KiCad-Diff/bin:${PATH}' | tee -a "${HOME}/.zshrc" -RUN echo 'export PATH=${KIRI_HOME}/bin:${PATH}' | tee -a "${HOME}/.zshrc" - -# custom commands -RUN echo | tee -a "${HOME}/.zshrc" -RUN echo '# Custom Commands' | tee -a "${HOME}/.zshrc" -RUN echo 'function ip() { awk "/32 host/ { print f } {f=\$2}" /proc/net/fib_trie | sort | uniq | grep -v 127.0.0.1 | head -n1 }' | tee -a "${HOME}/.zshrc" -RUN echo 'alias kiri="kiri -i \$(ip)"' | tee -a "${HOME}/.zshrc" - -# clean unnecessary stuff -RUN sudo apt-get purge -y \ - curl \ - opam \ - build-essential \ - pkg-config \ - libgmp-dev -RUN sudo apt-get -y autoremove -RUN sudo rm -rf \ - /tmp/* \ - /var/tmp/* \ - /usr/share/doc/* \ - /usr/share/info/* \ - /usr/share/man/* - -# initialize kicad config files to skip default popups of setup -COPY config /home/kiri/.config -RUN sudo chown -R kiri /home/kiri/.config - - -ARG DEBIAN_FRONTEND noninteractive - -RUN sudo apt-get update && \ - sudo apt-get install -y \ - apt-utils && \ - sudo apt-get install -y \ - unrar-free \ - wget \ - curl \ - bzip2 \ - librsvg2-bin \ - ghostscript && \ - sudo apt-get install -y --no-install-recommends \ - python3-qrcodegen \ - poppler-utils && \ - curl -s https://api.github.com/repos/INTI-CMNB/KiAuto/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/INTI-CMNB/KiBoM/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/INTI-CMNB/InteractiveHtmlBom/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/INTI-CMNB/PcbDraw/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/hildogjr/KiCost/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/INTI-CMNB/KiBot/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/set-soft/kicost-digikey-api-v3/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - && \ - curl -s https://api.github.com/repos/INTI-CMNB/kicad-git-filters/releases/latest | grep "browser_download_url.*deb" | cut -d : -f 2,3 | tr -d \" | wget -i - - -RUN sudo ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime -RUN sudo apt-get install -y --no-install-recommends tzdata - -RUN sudo apt install -y --no-install-recommends \ - ./python3-pymeta_0.5.1-1_all.deb \ - ./python3-pcbnewtransition_0.2.0-1_all.deb \ - ./python3-pybars_0.9.7-1_all.deb \ - ./python3-svgpathtools_1.4.1-1_all.deb \ - ./python3-validators_0.14.2-2_all.deb \ - ./kiauto_2.1.0-1_all.deb \ - ./kibom.inti-cmnb_1.8.0-3_all.deb \ - ./interactivehtmlbom.inti-cmnb_2.5.0-2_all.deb \ - ./pcbdraw_0.9.0-5_all.deb \ - ./kicost-digikey-api-v3_0.1.1-1_all.deb \ - ./kicost-digikey-api-v3_0.1.2-1_all.deb \ - ./kibot_1.5.1-1_all.deb \ - ./kicad-git-filters_1.0.1-1_all.deb && \ - sudo rm *.deb && \ - sudo apt-get purge -y \ - apt-utils \ - wget \ - curl && \ - sudo apt-get -y autoremove && \ - sudo rm -rf /var/lib/apt/lists/* - -RUN sudo sed -i 's///g' /etc/ImageMagick-6/policy.xml && \ - sudo sed -i 's///g' /etc/ImageMagick-6/policy.xml - -RUN sudo apt-get -y autoremove -RUN sudo rm -rf \ - /tmp/* \ - /var/tmp/* \ - /usr/share/doc/* \ - /usr/share/info/* \ - /usr/share/man/* diff --git a/Makefile b/Makefile deleted file mode 100644 index 05944d9..0000000 --- a/Makefile +++ /dev/null @@ -1,60 +0,0 @@ - -dockerfile = Dockerfile - -docker_username = leoheck -docker_repo = kiri -docker_tagname = latest - -docker_build: $(dockerfile) - time docker build \ - -f $(dockerfile) \ - --tag $(docker_username)/$(docker_repo):$(docker_tagname) . - docker images - -docker_build_no_cache: $(dockerfile) - time docker build \ - -f $(dockerfile) \ - --no-cache \ - --tag $(docker_username)/$(docker_repo):$(docker_tagname) . - docker images - - -docker_login: - docker login - -docker_push: docker_build - docker push $(docker_username)/$(docker_repo):$(docker_tagname) - - - -# get the latest kiri image from docker hub -docker_pull: - docker pull $(docker_username)/$(docker_repo):$(docker_tagname) - - -show_containers: - docker ps -a - -stop_all_docker_containers: - docker ps -q || docker kill $(shell docker ps -q) - -remove_all_docker_containers: - docker ps -a -q || docker rm $(shell docker ps -a -q) - -remove_all_docker_images: - docker images -q || docker rmi $(shell docker images -q | tac) - -system_prune: - make stop_all_docker_containers - make remove_all_docker_containers - make remove_all_docker_images - yes | docker system prune - - -.PHONY: run_test - -testcase_path = "/home/lheck/Documents/assoc-board" - -# Don't use this target, this is just my own test case -run_test: - ./kiri $(testcase_path) diff --git a/README.md b/README.md index abfd953..f898a29 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,84 @@ -# Kiri Docker - -Kiri Docker is a convenient and easy way to run [Kiri](https://github.com/leoheck/kiri) pre-installed in a Ubuntu container. - -> Kiri repo is not necessary to run Kiri Docker - -Kiri Docker works by mounting the user's project from the host machine inside the container. This way, the output files are easily accessible from the host system making it simple to visualize using the host's browser. - -The existing kiri image is hosted in Docker Hub here https://hub.docker.com/r/leoheck/kiri/tags - -# Getting the existing docker image - -The docker container can be donwloaded through this repo with: - -```bash -gh repo clone leoheck/kiri-docker -make docker_pull -``` - -Alternatively, you can pull the latest image file with: -```bash -docker pull leoheck/kiri:latest -``` - -# Building your own docker image - -It is also possible to build the docker image yourself, if needed: - -```bash -gh repo clone leoheck/kiri-docker -cd kiri-docker -make build -``` - -# Environment - -Download or build the docker image and then set your PATH to this repo with: - -```bash -export PATH="$(pwd)/kiri-docker/" -``` - -# Using Kiri Docker - -To run kiri on your Kicad project repository: - -```bash -kiri [OPTIONS] [REPO_PATH] [-k|--kiri [ARGS] -``` - -For extended arguments list, please use the flag `-h`. - -# Examples - -Just launch the container for manual exploration - -```bash -kiri -``` - -This example launches kiri (docker), passing the path of the project path and a parameter `-r` of kiri to remove old files. - -```bash -kiri "/home/lheck/Documents/assoc-board" -k -r -``` - -This, starts the container with the project folder and do nothing, so you can debug something manually. - -```bash -kiri "/home/lheck/Documents/assoc-board" -d +# Kiri Pull Request GitHub Action + +This is a convenient and easy way to run [Kiri](https://github.com/leoheck/kiri) against a Pull Request using GitHub Actions. + +The base Kiri image is hosted in the GitHub Container Repository here , +which is based on the Kiri image at + +## PR HTML Preview Setup + +In order to provide PRs with a link to preview the changes, this action pushes to the `gh-pages` branch of the source +repository and hosts the Kiri output in subdirectories. + +For this to work properly, you'll need to make an empty `gh-pages` branch with the file `.nojekyll` (to avoid `_KIRI_` folders returning a 404). + +### Deleting PRs on close + +Running this action in the context of `pull_request.closed` will delete any Kiri previews that were made for the PR. + +## Action inputs + +All inputs are **optional**. + +| Name | Description | +| ------------------------ | ------------------------------------------------------------------------ | +| `all` | If set, include all commits even if schematics/layout don't have changes | +| `last` | Show last N commits | +| `newer` | Show commits up to this one | +| `older` | Show commits starting from this one | +| `skip-cache` | If set, skip usage of -cache.lib on plotgitsch | +| `skip-kicad6-schematics` | If set, skip ploting Kicad 6 schematics (.kicad.sch) | +| `force-layout-view` | If set, force starting with the Layout view selected | +| `pcb-page-frame` | If set, disable page frame for PCB | +| `archive` | If set, archive generated files | +| `remove` | If set, remove generated folder before running it | +| `output-dir` | If set, change output folder path/name | +| `project-file` | Path to the KiCad project file | +| `extra-args` | Extra arguments to pass to Kiri | +| `kiri-debug` | If set, enable debugging output | + +## Examples + +```yaml +# .github/workflows/pr-kicad-diff.yaml +name: KiCad Diff Check + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - '*.kicad_pcb' + - '*.kicad_sch' + - '*.kicad_pro' + +jobs: + kiri: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Kiri + uses: usa-reddragon/kiri-github-action@v1 ``` -Launch kiri with a repo that has a nested kicad project (kicad project is not in the root path) - -```bash -kiri "/home/lheck/Documents/assoc-board" -k "nested_project/board.kicad_pro" -``` - -Starts docker binding project's repo, do not run kiri, and run pcbdraw command: -This example uses the image generated with `Dockerfile_kicad-auto`. - -```bash -kiri "/home/lheck/Documents/assoc-board" -i leoheck/kiri:test -d -c "pcbdraw board.kicad_pcb board.svg" +```yaml +# .github/workflows/pr-kicad-diff-delete.yaml +name: KiCad Diff Delete + +on: + pull_request: + types: + - closed + +jobs: + kiri: + runs-on: ubuntu-latest + steps: + - name: Kiri + uses: usa-reddragon/kiri-github-action@v1 ``` diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..903ffae --- /dev/null +++ b/action.yml @@ -0,0 +1,166 @@ +name: Kiri KiCad Diff Action +description: An action using Kiri to diff KiCad projects in CI +inputs: + project-file: + description: Path to the KiCad project file + output-dir: + description: Change output folder path/name + remove: + description: Remove generated folder before running it + archive: + description: Archive generated files + pcb-page-frame: + description: Disable page frame for PCB + force-layout-view: + description: Force starting with the Layout view selected + skip-kicad6-schematics: + description: Skip ploting Kicad 6 schematics (.kicad.sch) + skip-cache: + description: Skip usage of -cache.lib on plotgitsch + older: + description: Show commits starting from this one + newer: + description: Show commits up to this one + last: + description: Show last N commits + all: + description: Include all commits even if schematics/layout don't have changes + extra-args: + description: Extra arguments to pass to Kiri + kiri-debug: + description: Enable debug mode for Kiri +outputs: {} +runs: + using: composite + steps: + - name: Get number of commits in PR + if: github.event_name == 'pull_request' && (github.event_name == 'pull_request' && github.event.action != 'closed') + id: pr + shell: bash + run: | + # Set DEFAULT_LAST to the number of commits in the PR if ${{ inputs.last }} is not set. The minimum is 2. + if [ -z "${{ inputs.last }}" ]; then + # Un-shallow, but don't fail if it's already unshallow + git fetch --unshallow || true + git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" + # Deepen topic branch; checkout topic branch + git fetch origin ${{ github.event.pull_request.head.ref }} --depth=$(( ${{ github.event.pull_request.commits }} + 1 )) + git checkout ${{ github.event.pull_request.head.ref }} + # Fetch main for common origin + git fetch origin main:main + COUNT=$(git rev-list --count ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}) + echo "DEFAULT_LAST=\"${COUNT}\"" >> $GITHUB_ENV + else + echo "DEFAULT_LAST=\"${{ inputs.last }}\"" >> $GITHUB_ENV + fi + - name: Run Kiri + uses: docker://ghcr.io/usa-reddragon/kiri:v1.0.23 + if: github.event_name != 'pull_request' || github.event.action != 'closed' + env: + KIRI_PROJECT_FILE: ${{ inputs.project-file }} + KIRI_OUTPUT_DIR: ${{ inputs.output-dir }} + KIRI_REMOVE: ${{ inputs.remove }} + KIRI_ARCHIVE: ${{ inputs.archive }} + KIRI_PCB_PAGE_FRAME: ${{ inputs.pcb-page-frame }} + KIRI_FORCE_LAYOUT_VIEW: ${{ inputs.force-layout-view }} + KIRI_SKIP_KICAD6_SCHEMATICS: ${{ inputs.skip-kicad6-schematics }} + KIRI_SKIP_CACHE: ${{ inputs.skip-cache }} + KIRI_OLDER: ${{ inputs.older }} + KIRI_NEWER: ${{ inputs.newer }} + KIRI_LAST: ${{ steps.pr.outputs.DEFAULT_LAST }} + KIRI_ALL: ${{ inputs.all }} + KIRI_DEBUG: ${{ inputs.kiri-debug }} + KIRI_TAG: ${{ inputs.kiri-tag }} + with: + args: ${{ inputs.extra-args }} + - name: Upload Kiri custom output + uses: actions/upload-artifact@v2 + if: inputs.output-dir != '' && github.event_name == 'pull_request' && github.event.action != 'closed' + with: + name: kiri-output + path: ${{ inputs.output-dir }} + - name: Get Kiri output directory + id: kiri-output + if : inputs.output-dir == '' && github.event_name == 'pull_request' && github.event.action != 'closed' + shell: bash + run: | + # If output-dir is not set, the output directory is in the same folder as the project file, in the folder .kiri + # If the project file is not set, the output directory is simply .kiri + if [ -z "${{ inputs.project-file }}" ]; then + echo "output-dir=.kiri" >> $GITHUB_OUTPUT + else + echo "output-dir=$(dirname ${{ inputs.project-file }})/.kiri" >> $GITHUB_OUTPUT + fi + - name: Upload Kiri output + uses: actions/upload-artifact@v2 + if: inputs.output-dir == '' && github.event_name == 'pull_request' && github.event.action != 'closed' + with: + name: kiri-output + path: ${{ steps.kiri-output.outputs.output-dir }} + - name: Checkout gh-pages branch + if: github.event_name == 'pull_request' && github.event.action != 'closed' + uses: actions/checkout@v3 + with: + ref: gh-pages + fetch-depth: 0 + path: gh-pages + - name: Setup git config for gh-pages branch + if: github.event_name == 'pull_request' + shell: bash + run: | + cd gh-pages + git config --local user.email github-actions@github.com + git config --local user.name github-actions + - name: Copy the output to a subdirectory of the gh-pages branch + if: github.event_name == 'pull_request' && github.event.action != 'closed' + shell: bash + run: | + rm -rf gh-pages/pr-previews/${{ github.event.pull_request.number }} + mkdir -p gh-pages/pr-previews/${{ github.event.pull_request.number }} + cp -r ${{ steps.kiri-output.outputs.output-dir }}/* gh-pages/pr-previews/${{ github.event.pull_request.number }} + - name: Commit and push the changes + if: github.event_name == 'pull_request' && github.event.action != 'closed' + shell: bash + id: commit + run: | + cd gh-pages + git add -A + git commit -m "Update Kiri output for PR #${{ github.event.pull_request.number }}" + git push origin gh-pages + echo "repository_name=${REPO##*/}" >> $GITHUB_OUTPUT + env: + REPO: ${{ github.repository }} + - name: Create a comment with the link to the output + if: github.event_name == 'pull_request' && github.event.action != 'closed' + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.pull_request.number }} + body: | + Kiri diff output is available at https://${{ github.repository_owner }}.github.io/${{ steps.commit.outputs.repository_name }}/pr-previews/${{ github.event.pull_request.number }}/web/index.html + - name: Delete pr-previews/${{ github.event.pull_request.number }} + id: delete + shell: bash + if: github.event_name == 'pull_request' && github.event.action == 'closed' + run: + cd gh-pages + rm -rf pr-previews/${{ github.event.pull_request.number }} + if [ -n "$(git status --porcelain pr-previews/${{ github.event.pull_request.number }}" ]; then + git add -A + echo "deleted=true" >> $GITHUB_OUTPUT + else + echo "deleted=false" >> $GITHUB_OUTPUT + fi + - name: Commit and push + if: steps.delete.outputs.deleted == 'true' && github.event_name == 'pull_request' && github.event.action == 'closed' + shell: bash + run: + cd gh-pages + git commit -m "Delete pr-previews/${{ github.event.pull_request.number }}" + git push origin gh-pages + - name: Create a comment on the PR + if: steps.delete.outputs.deleted == 'true' && github.event_name == 'pull_request' && github.event.action == 'closed' + uses: peter-evans/create-or-update-comment@v1 + with: + issue-number: ${{ github.event.pull_request.number }} + body: | + Kiri diff output has been deleted. diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..272cb4b --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# This script is used to parse environment variable from the +# Github Actions workflow and run Kiri. + +if [ -n "${KIRI_DEBUG}" ]; then + set -x +fi + +# Get the current ownership of ${GITHUB_WORKSPACE} +# and change it to the current user. +OWNER_ID=$(stat -c '%u' ${GITHUB_WORKSPACE}) +GROUP_ID=$(stat -c '%g' ${GITHUB_WORKSPACE}) +if [ "${OWNER_ID}" != "${USER}" ]; then + sudo chown -R ${USER}:${USER} ${GITHUB_WORKSPACE} +fi + +. /home/github/.profile + +KIRI_ARGS="--no-server --no-error-on-commit-count" + +# KIRI_OUTPUT_DIR -> --output-dir +if [ -n "${KIRI_OUTPUT_DIR}" ]; then + KIRI_ARGS="${KIRI_ARGS} --output-dir ${KIRI_OUTPUT_DIR}" +fi + +# KIRI_REMOVE -> --remove +if [ -n "${KIRI_REMOVE}" ]; then + KIRI_ARGS="${KIRI_ARGS} --remove" +fi + +# KIRI_ARCHIVE -> --archive +if [ -n "${KIRI_ARCHIVE}" ]; then + KIRI_ARGS="${KIRI_ARGS} --archive" +fi + +# KIRI_PCB_PAGE_FRAME -> --page-frame +if [ -n "${KIRI_PCB_PAGE_FRAME}" ]; then + KIRI_ARGS="${KIRI_ARGS} --page-frame" +fi + +# KIRI_FORCE_LAYOUT_VIEW -> --layout +if [ -n "${KIRI_FORCE_LAYOUT_VIEW}" ]; then + KIRI_ARGS="${KIRI_ARGS} --layout" +fi + +# KIRI_SKIP_KICAD6_SCHEMATICS -> --skip-kicad6 +if [ -n "${KIRI_SKIP_KICAD6_SCHEMATICS}" ]; then + KIRI_ARGS="${KIRI_ARGS} --skip-kicad6" +fi + +# KIRI_SKIP_CACHE -> --skip-cache +if [ -n "${KIRI_SKIP_CACHE}" ]; then + KIRI_ARGS="${KIRI_ARGS} --skip-cache" +fi + +# KIRI_OLDER -> --older +if [ -n "${KIRI_OLDER}" ]; then + KIRI_ARGS="${KIRI_ARGS} --older ${KIRI_OLDER}" +fi + +# KIRI_NEWER -> --newer +if [ -n "${KIRI_NEWER}" ]; then + KIRI_ARGS="${KIRI_ARGS} --newer ${KIRI_NEWER}" +fi + +# KIRI_LAST -> --last +if [ -n "${KIRI_LAST}" ]; then + KIRI_ARGS="${KIRI_ARGS} --last ${KIRI_LAST}" +fi + +# KIRI_ALL -> --all +if [ -n "${KIRI_ALL}" ]; then + KIRI_ARGS="${KIRI_ARGS} --all" +fi + +# Run kiri and passthrough all arguments +kiri ${KIRI_ARGS} $@ ${KIRI_PROJECT_FILE} + +# Restore the ownership of ${GITHUB_WORKSPACE} +sudo chown -R ${OWNER_ID}:${GROUP_ID} ${GITHUB_WORKSPACE} diff --git a/kiri b/kiri deleted file mode 100755 index 360406e..0000000 --- a/kiri +++ /dev/null @@ -1,230 +0,0 @@ -#!/bin/bash - -# KIRI DOCKER - -show_help() -{ - read -r -d '' help_message <<- EOM - USAGE - - ${0} [OPTIONS] [REPO_PATH] [-k|--kiri [ARGS] - - OPTIONS - - -h|--help Show version - -v|--version Show version - -d|--dont-run Do not run kiri - -i|--docker-img IMG Set docker image, default is leoheck/kiri:tag - -c|--cmd CMD Run a command given by a string - -k|--kiri ARGS Pass a string with arguments to Kiri - - REPO_PATH - - If repo path is given it is mounted inside the container, - otherwise it is not used. If the repo path is given then - kiri will run by default, otherwise it won't. - - EOM - - echo -e "\n${help_message}\n" -} - -get_kiri_docker_version() -{ - local tool_path - local git_dir_path - local last_commit_hash - local last_commit_date - - tool_path=$(dirname "$(dirname "$(which ${0})")") - git_dir_path="${tool_path}/.git" - - if [[ -d "${git_dir_path}" ]]; then - last_commit_hash=$(git --git-dir "${git_dir_path}" rev-parse --short HEAD) - last_commit_date=$(git --git-dir "${git_dir_path}" log -1 --format="%at" | xargs -I{} date -d @{} +"%Y/%m/%d %Hh%M") - echo "${last_commit_hash} ${last_commit_date}" - else - echo "Unknown" - fi -} - -show_version() -{ - IFS= read -r -d '' VERSION <<-EOM - $(basename "${0}")-docker $(get_kiri_docker_version) - EOM - - printf "\n%s" "$VERSION" -} - -command_line_parse() -{ - run_kiri=1 - - while [[ ${#} -gt 0 ]]; do - - local key="${1}" - - case "${key}" in - - -h|--help) - show_help - exit 0 - ;; - - -v|--version) - shift - show_version - version_flag=1 - kiri_args="-v${kiri_args}" - ;; - - -d|--dont-run) - shift - run_kiri=0 - ;; - - -i|--docker-img) - docker_image=${2} - shift - shift - ;; - - -c|--cmd) - run_cmd="${2}" - shift - shift - ;; - - -k|--kiri) - shift - kiri_args="${kiri_args} ${@}" - break - ;; - - --*|-*) - echo "Unknown argument '${1}'" - exit 1 - ;; - - *) - repo_path="${1}" - shift - ;; - esac - done - - if [[ -n ${version_flag} ]] && [[ -z ${repo_path} ]]; then - exit 0 - fi -} - -main() -{ - shift - command_line_parse "${@}" - - repo_dir=$(basename "${repo_path}") - docker_repo_path="/home/kiri/${repo_dir}" - - if [[ -z "${docker_image}" ]]; then - container_img="leoheck/kiri" - else - container_img="${docker_image}" - fi - - container_name=kiri - container_tag=latest - - if echo "${kiri_args}" | grep -q -- '-v'; then - kiri_version_flag=1 - fi - - if [[ -z ${version_flag} ]] && [[ -z ${kiri_version_flag} ]]; then - echo - echo "| KiRI Docker" - echo "| Image: ${container_img}" - echo "| Container: ${container_name}" - - if [[ -n "${repo_path}" ]]; then - echo "| Repo Path: ${repo_path}" - fi - if [[ -n "${run_cmd}" ]]; then - echo "| Run Cmd: ${run_cmd}" - run_cmd="-c \"${run_cmd}\"" - fi - if [[ -n "${repo_path}" ]] && [[ -n "${kiri_args}" ]]; then - echo "| Kiri Args: $(echo ${kiri_args} | sed "s/^[ ]\+//g")" - fi - echo - fi - - # Run these in the host machine - XSOCK=/tmp/.X11-unix - XAUTH=/tmp/.docker.xauth - xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - - - setfacl -m user:1000:r "${HOME}/.Xauthority" - - if [[ -n "${repo_path}" ]]; then - if [[ "${run_kiri}" == "1" ]]; then - read -r -d '' KIRI_SCRIPT <<- EOM - cd "${docker_repo_path}" || exit 1 ;\ - sudo -H Xvfb -f \${DISPLAY} -screen 0 1280x800x24 -ac -dpi 96 +extension RANDR :1 > /dev/null 2>&1 \& ;\ - xvfb-run kiri -i \$(ip) ${kiri_args} ;\ - zsh -i - EOM - else - read -r -d '' KIRI_SCRIPT <<- EOM - cd "${docker_repo_path}" || exit 1 ;\ - zsh -i ${run_cmd} - EOM - fi - fi - - if [[ -n "${version_flag}" ]] || [[ -n "${kiri_version_flag}" ]]; then - read -r -d '' KIRI_SCRIPT <<- EOM - kiri ${kiri_args} - EOM - fi - - if [[ -z "${repo_path}" ]]; then - read -r -d '' KIRI_SCRIPT <<- EOM - zsh -i ${run_cmd} - EOM - fi - - if [[ -n "${repo_path}" ]]; then - docker run \ - -it \ - --rm \ - -e DISPLAY \ - --hostname="kiri" \ - --net=bridge \ - --name ${container_name} \ - --mount type=bind,source="${repo_path}",target="${docker_repo_path}" \ - -v ${XSOCK}:${XSOCK} \ - -v ${XAUTH}:${XAUTH} \ - -e XAUTHORITY=${XAUTH} \ - ${container_img} \ - zsh -i -c "${KIRI_SCRIPT}" - else - docker run \ - -it \ - --rm \ - -e DISPLAY \ - --hostname="kiri" \ - --net=bridge \ - --name ${container_name} \ - -v ${XSOCK}:${XSOCK} \ - -v ${XAUTH}:${XAUTH} \ - -e XAUTHORITY=${XAUTH} \ - ${container_img} \ - zsh -i -c "${KIRI_SCRIPT}" - fi - - # make sure the container has stoped - docker stop ${container_name} &> /dev/null -} - -main "${0}" "${@}"