diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..471d35d8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +# We only want to ignore these for the docker build +# I hope they are included in docker-compose... +/src/node_modules +/src/build diff --git a/.github/workflows/docker.build.yml b/.github/workflows/docker.build.yml new file mode 100644 index 00000000..3ddd3d35 --- /dev/null +++ b/.github/workflows/docker.build.yml @@ -0,0 +1,57 @@ +name: Docker build + +on: + push: + branches: + - 'main' + tags: + - '*' + pull_request: + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2.3.4 + - + name: Docker meta + id: docker_meta + uses: crazy-max/ghaction-docker-meta@v3.5.0 + with: + images: ghcr.io/${{ github.repository }} + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1.2.0 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1.5.1 + - + name: Cache Docker layers + uses: actions/cache@v2.1.6 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + - + name: Login to GitHub Container Registry + uses: docker/login-action@v1.10.0 + if: github.event_name != 'pull_request' + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v2.7.0 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,mode=max,dest=/tmp/.buildx-cache + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/docker.lint.yml b/.github/workflows/docker.lint.yml new file mode 100644 index 00000000..429940ac --- /dev/null +++ b/.github/workflows/docker.lint.yml @@ -0,0 +1,18 @@ +name: Docker lint + +on: + push: + branches: + - 'main' + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2.3.4 + - name: lint + uses: hadolint/hadolint-action@v1.6.0 + with: + dockerfile: Dockerfile \ No newline at end of file diff --git a/.github/workflows/github.prs.combine.yml b/.github/workflows/github.prs.combine.yml new file mode 100644 index 00000000..3a3973a6 --- /dev/null +++ b/.github/workflows/github.prs.combine.yml @@ -0,0 +1,136 @@ +# From https://github.com/testcontainers/testcontainers-java/blob/master/.github/workflows/combine-prs.yml +name: 'Combine PRs' + +# Controls when the action will run - in this case triggered manually +on: + workflow_dispatch: + inputs: + branchPrefix: + description: 'Branch prefix to find combinable PRs based on' + required: true + default: 'dependabot' + mustBeGreen: + description: 'Only combine PRs that are green (status is success)' + required: true + default: 'true' + combineBranchName: + description: 'Name of the branch to combine PRs into' + required: true + default: 'combine-prs-branch' + ignoreLabel: + description: 'Exclude PRs with this label' + required: true + default: 'nocombine' + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "combine-prs" + combine-prs: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/github-script@v5 + id: fetch-branch-names + name: Fetch branch names + with: + github-token: ${{secrets.GH_TOKEN_PLUSW}} + script: | + const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', { + owner: context.repo.owner, + repo: context.repo.repo + }); + branches = []; + prs = []; + base_branch = null; + for (const pull of pulls) { + const branch = pull['head']['ref']; + console.log('Pull for branch: ' + branch); + if (branch.startsWith('${{ github.event.inputs.branchPrefix }}')) { + console.log('Branch matched: ' + branch); + statusOK = true; + if(${{ github.event.inputs.mustBeGreen }}) { + console.log('Checking green status: ' + branch); + const checkRuns = await github.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { + owner: context.repo.owner, + repo: context.repo.repo, + ref: branch + }); + for await (const cr of checkRuns.data.check_runs) { + console.log('Validating check conclusion: ' + cr.conclusion); + if(cr.conclusion != 'success') { + console.log('Discarding ' + branch + ' with check conclusion ' + cr.conclusion); + statusOK = false; + } + } + } + console.log('Checking labels: ' + branch); + const labels = pull['labels']; + for(const label of labels) { + const labelName = label['name']; + console.log('Checking label: ' + labelName); + if(labelName == '${{ github.event.inputs.ignoreLabel }}') { + console.log('Discarding ' + branch + ' with label ' + labelName); + statusOK = false; + } + } + if (statusOK) { + console.log('Adding branch to array: ' + branch); + branches.push(branch); + prs.push('#' + pull['number'] + ' ' + pull['title']); + base_branch = pull['base']['ref']; + } + } + } + if (branches.length == 0) { + core.setFailed('No PRs/branches matched criteria'); + return; + } + core.setOutput('base-branch', base_branch); + core.setOutput('prs-string', prs.join('\n')); + combined = branches.join(' ') + console.log('Combined: ' + combined); + return combined + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2.3.3 + with: + fetch-depth: 0 + token: ${{ secrets.GH_TOKEN_PLUSW }} + # Creates a branch with other PR branches merged together + - name: Created combined branch + env: + BASE_BRANCH: ${{ steps.fetch-branch-names.outputs.base-branch }} + BRANCHES_TO_COMBINE: ${{ steps.fetch-branch-names.outputs.result }} + COMBINE_BRANCH_NAME: ${{ github.event.inputs.combineBranchName }} + run: | + echo "$BRANCHES_TO_COMBINE" + sourcebranches="${BRANCHES_TO_COMBINE%\"}" + sourcebranches="${sourcebranches#\"}" + basebranch="${BASE_BRANCH%\"}" + basebranch="${basebranch#\"}" + git config pull.rebase false + git config user.name github-actions + git config user.email github-actions@github.com + git branch $COMBINE_BRANCH_NAME $basebranch + git checkout $COMBINE_BRANCH_NAME + git pull origin $sourcebranches --no-edit + git push origin $COMBINE_BRANCH_NAME --force-with-lease + # Creates a PR with the new combined branch + - uses: actions/github-script@v5 + name: Create Combined Pull Request + env: + PRS_STRING: ${{ steps.fetch-branch-names.outputs.prs-string }} + with: + github-token: ${{secrets.GH_TOKEN_PLUSW}} + script: | + const prString = process.env.PRS_STRING; + const body = 'This PR was created by the Combine PRs action by combining the following PRs:\n' + prString; + await github.pulls.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: 'Combined PR for prefix: ${{ github.event.inputs.branchPrefix }}', + head: '${{ github.event.inputs.combineBranchName }}', + base: '${{ steps.fetch-branch-names.outputs.base-branch }}', + body: body + }); diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..918ffaac --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,58 @@ +# WBStack queryservice-ui + +## 1.4 + +Feburary 2022 updates from upstream. +Security patches. +Includes hotfix until upstream [bug](https://phabricator.wikimedia.org/T301255) is resolved + +## 1.3 + +June 2021 updates from upstream. + +## 1.2 + +January 2021 updates from upstream. + +## 1.1 + +December 2020 updates from upstream. [PR](https://github.com/wbstack/queryservice-ui/pull/1) + +## 1.0 + +Github Build (first) + +## May 2020 + +- 0.26 - Build: remove more non modified files from wbstack git (pt2) +- 0.25 - git pull, (2 may 2020) +- 0.21 - Build: without having all code files in wbstack git + +## April 2029 + +- 0.20 - git pull, (17 April 2020) +- 0.19 - git pull, (5 April 2020) + +## December 2019 + +- 0.18 - git pull, should fix https://github.com/addshore/wbstack/issues/32 ([edit] in examples) + +## November 2019 + +- 0.17 - 2x XSS fixes +- 0.16 - Help examples link fix / rewrite on load +- 0.15 - Examples button +- 0.14 - Tidy up after security fix +- 0.13 - SECURITY fix - https://phabricator.wikimedia.org/T233213 (XSS in math) + +## October 2019 + +- 0.12 - THURSDAY, tiny fix to title +- 0.11 - THURSDAY, fix config generation (missing first /) +- 0.10 - Wednesday before Wikidatacon +- 0.6 - Better dev localhost stuff +- 0.5 - Don't try to get last updated time (it wont work) +- 0.4 - Also allow sparql and wikibase config for localhost development +- 0.3 - CSS hacks to make the UI smaller and remove wikidata things +- 0.2 - sparql and wikibase API based on request host +- 0.1 - Initial version. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..c28167b7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM node:12 as builder + +WORKDIR /src/app + +COPY package.json package-lock.json ./ + +# TODO remove the --force from the install... +RUN npm install --force && npm cache clean --force + +COPY . . + +RUN npm run-script build + + +FROM nginx:1-alpine +LABEL org.opencontainers.image.source="https://github.com/wbstack/queryservice-ui" + + +COPY ./docker/default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder --chown=nginx:nginx /src/app/build /usr/share/nginx/html diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..c50cdb17 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,10 @@ +version: "3.7" +services: + debug: + image: node:12-alpine + working_dir: /home/node/app + command: npm start + volumes: + - ./src:/home/node/app + expose: + - "8080" diff --git a/docker/default.conf b/docker/default.conf new file mode 100644 index 00000000..15a58229 --- /dev/null +++ b/docker/default.conf @@ -0,0 +1,35 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name localhost; + charset utf-8; + + # files transfer + client_body_in_file_only clean; + client_body_buffer_size 32K; + client_max_body_size 1026g; + sendfile on; + send_timeout 300s; + + # redirect server error pages / and set response status to 200 / ok + #error_page 404 =200 /; + + root /usr/share/nginx/html; + index index.html index.html; + + # Always serve index.html for any request +# location / { +# root /usr/share/nginx/html; +# try_files $uri /index.html; +# } + + # deny access to .htaccess files, if Apache's document root concurs with nginx's one + location ~ /\.ht { + deny all; + } + + # deny access to hidden files (beginning with a period) + location ~ /\. { + access_log off; log_not_found off; deny all; + } +} diff --git a/index.html b/index.html index 539d3454..da674144 100644 --- a/index.html +++ b/index.html @@ -441,6 +441,14 @@