diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..772f455 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,104 @@ +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: [ "master" , "develop" , "patch-*" ] + # Publish semver tags as releases. + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "master", "develop" , "patch-*" ] + +env: + # Use docker.io for Docker Hub if empty + # REGISTRY: ghcr.io + REGISTRY: docker.io + # github.repository as / + 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@7e0881f8fe90b25e305bbf0309761e9314607e25 + with: + cosign-release: 'v1.9.0' + + # You may pin to the exact commit or the version. + # uses: docker/setup-qemu-action@8b122486cedac8393e77aa9734c3528886e4a1a8 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + # 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.REGISTRY_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 }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }} + + # 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' }} + platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/arm/v7,linux/arm/v5 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max + # 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 }} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7fcb16a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "markdownlint.config": { + "default": true, + "MD033": { + "allowed_elements": ["kbd"] + } + } +} diff --git a/Dockerfile b/Dockerfile index 197c110..c11caef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM nginx:1.23 +FROM nginx:latest + LABEL maintainer "fraoustin@gmail.com" COPY ./src/default.conf /etc/nginx/conf.d/default.conf @@ -9,7 +10,8 @@ RUN chmod +x /entrypoint.sh ENV SET_CONTAINER_TIMEZONE false ENV CONTAINER_TIMEZONE "" -RUN apt-get update && apt-get install -y \ +RUN apt-get update \ + && apt-get install -y \ apache2-utils \ fcgiwrap \ git \ @@ -19,7 +21,8 @@ RUN apt-get update && apt-get install -y \ libcgi-pm-perl \ mime-support \ spawn-fcgi \ - && rm -rf /var/lib/apt/lists/* + && apt-get autoclean \ + && rm -rf /var/lib/apt/lists/* # manage user load fcgiwrap RUN sed -i "s/www-data/nginx/g" /etc/init.d/fcgiwrap @@ -43,6 +46,7 @@ RUN chmod +x /usr/bin/rmauth # manage default value ENV GITUSER gituser ENV GITPASSWORD gitpassword +ENV GITHIGHLIGHT 0 # add ihm mdl ENV IHM no-mdl @@ -50,9 +54,23 @@ COPY ./src/ihm /mdl-ihm RUN cp /usr/share/gitweb/static/gitweb.css /usr/share/gitweb/static/gitweb.css.original RUN mkdir /usr/share/gitweb/ihm -VOLUME /var/lib/git -WORKDIR /var/lib/git +# force push to upstream +WORKDIR /opt/gitweb/ +COPY ./src/hooks/post-receive /opt/gitweb/post-receive +RUN chmod +x /opt/gitweb/post-receive +ENV FORCEPUSH "" + +# Setting base url via Docker +ENV URLPATH / + +VOLUME /opt/gitweb/remote/ + +VOLUME /var/lib/git/ + +WORKDIR /var/lib/git/ + EXPOSE 80 ENTRYPOINT ["/entrypoint.sh"] + CMD ["app"] diff --git a/README.md b/README.md index 4bf9dbc..7ad56f4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Docker Image for gitweb -generate a nginx server with git server and gitweb for ihm on http://127.0.0.1/ +generate a nginx server with git server and gitweb for ihm on load when start image load file in @@ -14,11 +14,14 @@ load when start image load file in - GITPROJECT - GITUSER (default gituser) - GITPASSWORD (default gitpassword) +- GITHIGHLIGHT (default `0`) - IHM (default "") +- FORCEPUSH ("" or every not blank string) manage force push to upstream when Downstream branch push ## Volume -- /var/lib/git +- git project: */var/lib/git/* +- git remove add: */opt/gitweb/remote/* ## Port @@ -35,29 +38,117 @@ load when start image load file in run image fraoustin/gitweb - docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "GITPROJECT=test" -v :/var/lib/git --name test -p 80:80 fraoustin/gitweb +```bash + docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "GITPROJECT=test" \ + -v :/var/lib/git --name test -p 80:80 fraoustin/gitweb +``` + +> use ^ for *CMD* OR ` for *Powershell* user default is gituser and password default is gitpassword -you use http://localhost/ for access gitweb +- You can change user and password by variable environment + +you use for access gitweb + +you can add remote + +```bash + git remote add origin http://gituser:gitpassword@localhost/test.git +``` + +you can push project + +when fist push + +```bash + git push --set-upstream origin master +``` + +other branch + +```bash + git branch --set-upstream-to=/ + +eg: + git branch --set-upstream-to=gitweb/main main +``` + +every next time push + +```bash + git push +``` + +or manual push + +```bash + git push origin # remote name +``` you can clone project +```bash git clone http://gituser:gitpassword@localhost/test.git +``` + +you can pull project when upstream update -You can change user and password by variable environment +```bash + git pull +``` +more use see: + +- +- + +## Add upstream and push + +creat *remotes.txt* +eg: + +```text +gitweb-test1 https://gituser:gitpassword@gitweb-test1 +gitweb-test2 https://gituser:gitpassword@gitweb-test2 +gitweb-test3 https://gituser:gitpassword@gitweb-test3 +``` + +run image fraoustin/gitweb + +```bash + docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "GITPROJECT=test" \ + -e FORCEPUSH='not_blank_string' \ + -v :/var/lib/git/ \ + -v :/opt/gitweb/remote/ \ + --name test -p 80:80 fraoustin/gitweb +``` + +if don't want force push, **DO NOT** set environment: FORCEPUSH + +- when run `addrepos ${project}` , + - will add hook: `hooks/post-receive` + - will add remote each: `add remote gitweb-test1 https://gituser:gitpassword@gitweb-test1/${project}.git` ... +- when downstream push + - gitweb will push to upstreams each: `git push [-f] --all gitweb-test1` ... + +## Setting base url via Docker environment + +use environment *URLPATH* to set base url ## Usage by Dockerfile Sample of Dockerfile +```Dockerfile FROM fraoustin/gitweb COPY ./00_init.sh /usr/share/gitweb/docker-entrypoint.pre/00_init.sh RUN chmod +x -R /usr/share/gitweb/docker-entrypoint.pre +``` File 00_init.sh +```bash #!/bin/bash REPOS='/var/lib/git/test.git' if [ ! -d $REPOS ]; then @@ -67,17 +158,20 @@ File 00_init.sh chgrp -R nginx . fi addauth $GITUSER $GITPASSWORD +``` build image mygit +```bash docker build -t mygit . +``` run image mygit - docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "GITUSER=gituser" -e "GITPASSWORD=gitpassword" -v :/var/lib/git --name test -p 80:80 mygit - - - +```bash + docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "GITUSER=gituser" -e "GITPASSWORD=gitpassword" \ + -v :/var/lib/git --name test -p 80:80 mygit +``` ## IHM material design @@ -85,5 +179,6 @@ If you want use a new design for ihm, you can use IHM variable - IHM = mdl +```bash docker run -d -e "CONTAINER_TIMEZONE=Europe/Paris" -e "IHM=mdl" -e "GITPROJECT=test" -v :/var/lib/git --name test -p 80:80 fraoustin/gitweb - +``` diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..c3a3845 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,28 @@ +version: "3" + +volumes: + gitweb: + + +services: + gitweb: + image: fraoustin/gitweb + container_name: gitweb + hostname: gitweb-test + # build: + # context: https://github.com/fraoustin/gitweb.git + # dockerfile: Dockerfile + environment: + - CONTAINER_TIMEZONE=Europe/Paris + - GITUSER=gituser + - GITPASSWORD=gitpassword + - GITPROJECT=test + - FORCEPUSH="" + - URLPATH=/ + - GITHIGHLIGHT=1 + ports: + - 80:80 + restart: always + volumes: + - gitweb:/var/lib/git/ + - /path/to/remote/:/opt/gitweb/remote/ diff --git a/src/00_init.sh b/src/00_init.sh index d06a38a..4cc41e0 100755 --- a/src/00_init.sh +++ b/src/00_init.sh @@ -4,8 +4,6 @@ if [ ! -z "$GITPROJECT" ]; then if [ ! -d $REPOS ]; then addrepos $GITPROJECT cd $REPOS - chmod -R g+ws . - chgrp -R nginx . fi fi if [ ! -z "$GITUSER" ]; then diff --git a/src/cmd/addrepos.sh b/src/cmd/addrepos.sh index 976bec8..ea4e9da 100644 --- a/src/cmd/addrepos.sh +++ b/src/cmd/addrepos.sh @@ -1,25 +1,47 @@ #!/bin/bash + DIR="/var/lib/git/" - + +log_run(){ + echo -e "$@" + eval $@ +} + error(){ - echo "ERROR : parameters invalid !" >&2 - exit 1 + echo "ERROR : parameters invalid !" >&2 + exit 1 } usage(){ - echo "Usage: addrepos NameOfRepository" - echo "--help or -h : view help" + echo "Usage: addrepos NameOfRepository" + echo "--help or -h : view help" } load(){ - REPOS=$DIR$1.git - if [ ! -d $REPOS ]; then - mkdir $REPOS - cd $REPOS - git init --bare - echo "$1" > description - chmod -R 777 $REPOS - fi + REPOS=$DIR$1.git + if [ ! -d $REPOS ]; then + mkdir $REPOS + cd $REPOS + git init --bare + echo "$1" > description + chmod -R g+ws . + chgrp -R nginx . + if [ ! -f /opt/gitweb/remote/remotes.txt ]; then + exit 0 + fi + log_run cp /opt/gitweb/post-receive $REPOS/hooks/post-receive + log_run chgrp nginx $REPOS/hooks/post-receive + log_run chmod 0755 $REPOS/hooks/post-receive + log_run chmod g+ws $REPOS/hooks/post-receive + while read line + do + if [ -z "${line}" ];then + continue + fi + # eg: git remote add gitweb-test1 https://gituser:gitpassword@gitweb-test1/test.git + log_run git remote add ${line}/$(basename $(pwd)) + done < /opt/gitweb/remote/remotes.txt + fi } # no parameters @@ -29,12 +51,12 @@ case "$1" in --help) usage ;; - + -h) usage ;; - + *) load $1 - + esac diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 07a910a..dae2d20 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -29,7 +29,17 @@ if [ "$1" = 'app' ]; then echo '$site_footer="ihm/footer.html";' >> /etc/gitweb.conf cat /usr/share/gitweb/ihm/headstring.conf >> /etc/gitweb.conf cp /usr/share/gitweb/ihm/gitweb.css /usr/share/gitweb/static/gitweb.css - fi + fi + if [ "$GITHIGHLIGHT" = "1" ]; then + echo '' >> /etc/gitweb.conf + echo '# enable syntax highlighting' >> /etc/gitweb.conf + echo "\$feature{'highlight'}{'default'} = [1];" >> /etc/gitweb.conf + fi + if [ -n "${URLPATH}" ]; then + sed -n '10p' /etc/nginx/conf.d/default.conf + sed -i "10s|.*| location ${URLPATH} {|" /etc/nginx/conf.d/default.conf + sed -n '10p' /etc/nginx/conf.d/default.conf + fi service fcgiwrap start nginx -g "daemon off;" /bin/run-parts --verbose --regex '\.(sh)$' "/usr/share/gitweb/docker-entrypoint.post" diff --git a/src/hooks/post-receive b/src/hooks/post-receive new file mode 100644 index 0000000..44f25eb --- /dev/null +++ b/src/hooks/post-receive @@ -0,0 +1,40 @@ +#!/bin/bash + +log_info(){ + echo -e "\033[32m$(date +%Y-%m-%d_%H:%M:%S) - $@\033[0m" +} +log_warn(){ + echo -e "\033[33m$(date +%Y-%m-%d_%H:%M:%S) - $@\033[0m" +} +log_error(){ + echo >&2 -e "\033[31m$(date +%Y-%m-%d_%H:%M:%S) - $@\033[0m" +} +log_run(){ + echo -e "\033[43;34m$@\033[0m" + eval $@ +} + +IS_BARE=$(git rev-parse --is-bare-repository) +if [ -z "$IS_BARE" ]; then + log_error "fatal: post-receive: IS_NOT_BARE" + exit 1 +fi +log_warn "========================= deploy start =========================" +HOSTNAME="$(hostname)" +log_warn "========================= hostname: ${HOSTNAME}" + +git_push(){ + log_warn "========================= push start" + for remote in $(git remote) + do + log_info ${HOSTNAME} push to ${remote} + log_run git push ${FORCEPUSH:+ -f} --all ${remote} + done + log_warn "========================= push end" +} + + +log_info "try run : git_push" +git_push + +log_warn "========================= deploy end =========================" diff --git a/test/remotes.txt b/test/remotes.txt new file mode 100644 index 0000000..06b4e39 --- /dev/null +++ b/test/remotes.txt @@ -0,0 +1,3 @@ +gitweb-test1 https://gituser:gitpassword@gitweb-test1 +gitweb-test2 https://gituser:gitpassword@gitweb-test2 +gitweb-test3 https://gituser:gitpassword@gitweb-test3 \ No newline at end of file