diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6ef224c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Set line ending normalization +# *.txt text eol=lf # Treat files with .txt extension as text files with LF (Unix-style) line endings +# *.csv text eol=crlf # Treat files with .csv extension as text files with CRLF (Windows-style) line endings + +# Go Project +*.sql linguist-language=GO +*.html linguist-language=GO \ No newline at end of file diff --git a/.github/.codecov.yml b/.github/.codecov.yml new file mode 100644 index 0000000..6fa6048 --- /dev/null +++ b/.github/.codecov.yml @@ -0,0 +1,25 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +coverage: + status: + project: + default: false + pkg: + paths: + - server/pkg/* + - server/internal/* + - server/example/* + informational: true + patch: off \ No newline at end of file diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..ed182e1 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,51 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Refer to Kubernetes for size/* Settings +# https://github.com/Kubernetes/Kubernetes +XS: + name: size/XS + lines: 0 + color: 3CBF00 +S: + name: size/S + lines: 10 + color: 5D9801 +M: + name: size/M + lines: 30 + color: 7F7203 +L: + name: size/L + lines: 100 + color: A14C05 +XL: + name: size/XL + lines: 500 + color: C32607 +XXL: + name: size/XXL + lines: 1000 + color: E50009 + comment: | + ## πŸ€– Whoa! Easy there, Partner! + This PR is too big. It's over 1000. Please break it up into smaller PRs. + +XXXL: + name: size/XXXL + lines: 5000 + color: FF0000 + comment: | + ## πŸ€– Whoa! Easy there, Partner! + This PR is too big. It's over 5000. Please break it up into smaller PRs. \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..154386f --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,51 @@ +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name-template: 'v$RESOLVED_VERSION 🌈' +tag-template: 'v$RESOLVED_VERSION' +categories: + - title: 'πŸš€ Features' + labels: + - 'feature' + - 'enhancement' + - title: 'πŸ› Bug Fixes' + labels: + - 'kind/fix' + - 'kind/feature' + - 'enhancement' + - 'kind/documentation' + - 'good first issue' + - title: '🧰 Maintenance' + label: 'chore' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Changes $PREVIOUS_TAG + + $CHANGES + + ## Contributors to this $REPOSITORY release + + $CONTRIBUTORS \ No newline at end of file diff --git a/.github/sync.yml b/.github/sync.yml new file mode 100644 index 0000000..583b9aa --- /dev/null +++ b/.github/sync.yml @@ -0,0 +1,20 @@ +# Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# https://github.com/BetaHuhn/repo-file-sync-action +# Synchronization for the.github repository +interview/interview: + - source: ./ + dest: ./ + replace: true \ No newline at end of file diff --git a/.github/weekly-digest.yml b/.github/weekly-digest.yml new file mode 100644 index 0000000..d1159c4 --- /dev/null +++ b/.github/weekly-digest.yml @@ -0,0 +1,20 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +publishDay: sun +canPublishIssues: true +canPublishPullRequests: true +canPublishContributors: true +canPublishStargazers: true +canPublishCommits: true \ No newline at end of file diff --git a/.github/workflows/auto-assign-issue.yml b/.github/workflows/auto-assign-issue.yml new file mode 100644 index 0000000..f09d90b --- /dev/null +++ b/.github/workflows/auto-assign-issue.yml @@ -0,0 +1,43 @@ +# Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Assign issue to comment author +on: + issue_comment: + types: [created] +jobs: + assign-issue: + if: | + contains(github.event.comment.body, '/assign') || contains(github.event.comment.body, '/accept') && + !contains(github.event.comment.user.login, 'openimbot') && + !contains(github.event.comment.user.login, 'kubbot') + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Assign the issue + run: | + export LETASE_MILESTONES=$(curl 'https://api.github.com/repos/$OWNER/$PEPO/milestones' | jq -r 'last(.[]).title') + gh issue edit ${{ github.event.issue.number }} --add-assignee "${{ github.event.comment.user.login }}" + gh issue edit ${{ github.event.issue.number }} --add-label "triage/accepted" + gh issue edit ${{ github.event.issue.number }} --milestone "$LETASE_MILESTONES" + gh issue comment $ISSUE --body "@${{ github.event.comment.user.login }} Glad to see you accepted this issue🀲, this issue has been assigned to you. I set the milestones for this issue to [$LETASE_MILESTONES](https://github.com/$OWNER/$PEPO/milestones), We are looking forward to your PR!" + env: + GH_TOKEN: ${{ secrets.REDBOT_GITHUB_TOKEN }} + ISSUE: ${{ github.event.issue.html_url }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} \ No newline at end of file diff --git a/.github/workflows/auto-gh-pr.yml b/.github/workflows/auto-gh-pr.yml new file mode 100644 index 0000000..626265b --- /dev/null +++ b/.github/workflows/auto-gh-pr.yml @@ -0,0 +1,70 @@ +# Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Auto PR to release + +on: + pull_request: + # types: + # - closed + +jobs: + create-pr: + runs-on: ubuntu-latest + if: github.event.pull_request.base.ref == 'main' + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup GitHub CLI + run: | + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key C99B11DEB97541F0 + sudo apt-add-repository https://cli.github.com/packages + sudo apt-get update + sudo apt-get install gh + continue-on-error: true + + # - name: Configure GitHub CLI + # run: | + # git config --global user.email "3293172751ysy@gmail.com" + # git config --global user.name "kubbot" + # echo "${{ secrets.BOT_GITHUB_TOKEN }}" | gh auth login --with-token + - name: Create PR to release branch + run: | + ISSUEID=$(gh pr view ${{ github.event.pull_request.number }} --repo $OWNER/$REPO | grep -oP 'Fixes #\K\d+') + echo "===========> $ISSUEID" + ISSUE=$(gh issue view $ISSUEID --repo $OWNER/$REPO --json labels,assignees,milestone,title) + echo "===========> $ISSUE" + + LABELS=$(echo $ISSUE | jq -r '.labels[] | select(.name) | .name' | jq -R -r -s -c 'split("\n")[:-1] | join(",")') + ASSIGNEES=$(echo $ISSUE | jq -r '.assignees[] | select(.login) | .login' | jq -R -s -c 'split("\n")[:-1] | join(",")') + MILESTONE=$(echo $ISSUE | jq -r '.milestone | select(.title) | .title') + TITLE=$(echo $ISSUE | jq -r '.title') + + gh pr edit ${{ github.event.pull_request.number }} --repo $OWNER/$REPO --add-label "$LABELS" --add-assignee "$ASSIGNEES" --milestone "$MILESTONE" + + git checkout -b bot/merge-to-release-$ISSUEID + git push origin bot/merge-to-release-$ISSUEID + gh pr create --base release --head bot/merge-to-release-$ISSUEID --title "Merge main to release" --body "" + + # gh pr create --base main --head feat/auto-release-pr-624 --title "The bug is fixed" --body "$x" --repo aicworld/Open-IM-Server --reviewer "cubxxw" + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + GH_TOKEN: ${{ github.token }} + ISSUE: ${{ github.event.issue.html_url }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} \ No newline at end of file diff --git a/.github/workflows/auto-invite.yml b/.github/workflows/auto-invite.yml new file mode 100644 index 0000000..a0906c4 --- /dev/null +++ b/.github/workflows/auto-invite.yml @@ -0,0 +1,53 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Invite users to join our group +on: + issue_comment: + types: + - created +jobs: + issue_comment: + name: Invite users to join our group + if: ${{ github.event.comment.body == '/invite' || github.event.comment.body == '/close' || github.event.comment.body == '/comment' }} + runs-on: ubuntu-latest + permissions: + issues: write + steps: + + - name: Invite user to join our group + uses: peter-evans/create-or-update-comment@v1 + with: + token: ${{ secrets.BOT_GITHUB_TOKEN }} + issue-number: ${{ github.event.issue.number }} + body: | + We value close connections with our users, developers, and contributors here at Open-IM-Server. With a large community and maintainer team, we're always here to help and support you. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us. + + Our most recommended way to get in touch is through [Slack](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg). Even if you're in China, Slack is usually not blocked by firewalls, making it an easy way to connect with us. Our Slack community is the ideal place to discuss and share ideas and suggestions with other users and developers of Open-IM-Server. You can ask technical questions, seek help, or share your experiences with other users of Open-IM-Server. + + In addition to Slack, we also offer the following ways to get in touch: + + + We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [πŸ‘€ Open-IM-Server slack](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel. + + Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email. + + Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with Open-IM-Server projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information. + + Add [Wechat](https://github.com/aicworld/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of Open-IM-Server. We will process your request as soon as possible. + + - name: Close Issue + uses: peter-evans/close-issue@v3 + with: + token: ${{ secrets.BOT_GITHUB_TOKEN }} + issue-number: ${{ github.event.issue.number }} + comment: πŸ€– Auto-closing issue, if you still need help please reopen the issue or ask for help in the community above + labels: | + triage/accepted \ No newline at end of file diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml new file mode 100644 index 0000000..66cdb52 --- /dev/null +++ b/.github/workflows/build-docker-image.yml @@ -0,0 +1,251 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Publish interview Docker image + +on: + push: + branches: + - main + - release-* + tags: + - v* + workflow_dispatch: + +env: + # Common versions + GO_VERSION: "1.20" + +jobs: + build-server-dockerhub: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + +# docker.io/openim/openim-server:latest + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4.6.0 + with: + images: openim/interview-server + # generate Docker tags based on the following events/attributes + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.server + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + build-server-aliyun: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 +# registry.cn-hangzhou.aliyuncs.com/aicworld/openim-server:latest + - name: Extract metadata (tags, labels) for Docker + id: meta2 + uses: docker/metadata-action@v4.6.0 + with: + images: registry.cn-hangzhou.aliyuncs.com/aicworld/interview-server + + - name: Log in to AliYun Docker Hub + uses: docker/login-action@v2 + with: + registry: registry.cn-hangzhou.aliyuncs.com + username: ${{ secrets.ALIREGISTRY_USERNAME }} + password: ${{ secrets.ALIREGISTRY_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.server + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta2.outputs.tags }} + labels: ${{ steps.meta2.outputs.labels }} + + build-server-ghcr: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 +# ghcr.io/aicworld/openim-server:latest + - name: Extract metadata (tags, labels) for Docker + id: meta3 + uses: docker/metadata-action@v4.6.0 + with: + images: ghcr.io/aicworld/interview-server + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.server + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta3.outputs.tags }} + labels: ${{ steps.meta3.outputs.labels }} + + build-web-dockerhub: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + +# docker.io/openim/openim-web:latest + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4.6.0 + with: + images: openim/interview-web + # generate Docker tags based on the following events/attributes + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.web + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + build-web-aliyun: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 +# registry.cn-hangzhou.aliyuncs.com/aicworld/openim-web:latest + - name: Extract metadata (tags, labels) for Docker + id: meta2 + uses: docker/metadata-action@v4.6.0 + with: + images: registry.cn-hangzhou.aliyuncs.com/aicworld/interview-web + + - name: Log in to AliYun Docker Hub + uses: docker/login-action@v2 + with: + registry: registry.cn-hangzhou.aliyuncs.com + username: ${{ secrets.ALIREGISTRY_USERNAME }} + password: ${{ secrets.ALIREGISTRY_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.web + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta2.outputs.tags }} + labels: ${{ steps.meta2.outputs.labels }} + + build-web-ghcr: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 +# ghcr.io/aicworld/openim-web:latest + - name: Extract metadata (tags, labels) for Docker + id: meta3 + uses: docker/metadata-action@v4.6.0 + with: + images: ghcr.io/aicworld/interview-web + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/docker/Dockerfile.web + # linux/ppc64le,linux/s390x + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta3.outputs.tags }} + labels: ${{ steps.meta3.outputs.labels }} diff --git a/.github/workflows/check-coverage.yml b/.github/workflows/check-coverage.yml new file mode 100644 index 0000000..b14254c --- /dev/null +++ b/.github/workflows/check-coverage.yml @@ -0,0 +1,60 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Check-Coverage + + +on: + workflow_dispatch: + push: + branches: [ "main" ] + paths-ignore: + - "docs/**" + - "**/*.md" + - "**/*.yaml" + - "CONTRIBUTORS" + - "CHANGELOG/**" + pull_request: + branches: [ "*" ] + paths-ignore: + - "docs/**" + - "**/*.md" + - "**/*.yaml" + - "CONTRIBUTORS" + - "CHANGELOG/**" +env: + # Common versions + GO_VERSION: "1.20" + +jobs: +# coverage: +# runs-on: ubuntu-20.04 +# steps: +# - name: Checkout +# uses: actions/checkout@v3 + +# - name: Setup Golang with cache +# uses: magnetikonline/action-golang-cache@v3 +# with: +# go-version: ${{ env.GO_VERSION }} +# token: ${{ secrets.BOT_GITHUB_TOKEN }} + +# - name: Install Dependencies +# run: sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev + +# - name: Run Cover +# run: make cover + +# - name: Upload Coverage to Codecov +# uses: codecov/codecov-action@v3 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 0000000..1383c30 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,62 @@ +# Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: "OpenIM CLA Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened,closed,synchronize] + +# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings +permissions: + actions: write + contents: write + pull-requests: write + statuses: write + +env: + # Define Open-IM-Server variables here + OPEN_IM_SERVER_REMOTE_ORGANIZATION: openim-sigs + REMOTE_REPOSITORY: cla + OPEN_IM_SERVER_CLA_DOCUMENT: https://github.com/openim-sigs/cla/blob/main/README.md + OPEN_IM_SERVER_SIGNATURES_PATH: signatures/${{ github.event.repository.name }}/cla.json + + OPEN_IM_SERVER_ALLOWLIST: kubbot,bot* + +jobs: + CLAAssistant: + runs-on: ubuntu-latest + steps: + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@v2.3.0 + env: + GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.REDBOT_GITHUB_TOKEN }} + with: + path-to-signatures: ${{ env.OPEN_IM_SERVER_SIGNATURES_PATH }} + path-to-document: ${{ env.OPEN_IM_SERVER_CLA_DOCUMENT }} + branch: 'main' + allowlist: ${{ env.OPEN_IM_SERVER_ALLOWLIST }} + + remote-organization-name: ${{ env.OPEN_IM_SERVER_REMOTE_ORGANIZATION }} + remote-repository-name: ${{ env.REMOTE_REPOSITORY }} + + create-file-commit-message: 'πŸ“š Docs: Creating file for storing ${{ github.event.repository.name }} CLA Signatures' + custom-notsigned-prcomment: 'πŸ’• Thank you for your contribution and please kindly read and sign our [🎯https://github.com/openim-sigs/cla/blob/main/README.md](https://github.com/openim-sigs/cla/blob/main/README.md).
If you wish to sign the CRA, **Please copy and comment on the following sentence:**' + custom-pr-sign-comment: 'I have read the CLA Document and I hereby sign the CLA' + custom-allsigned-prcomment: 'πŸ€– All Contributors have signed the [${{ github.event.repository.name }} CLA](https://github.com/openim-sigs/cla/blob/main/README.md).
The signed information is recorded [πŸ€–here](https://github.com/openim-sigs/cla/tree/main/signatures/${{ github.event.repository.name }}/cla.json)' + # lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) + # use-dco-flag: true - If you are using DCO instead of CLA diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..6233ffc --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,76 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +name: "Code Scanning - Action" + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute (0 - 59) + # β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour (0 - 23) + # β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of the month (1 - 31) + # β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ month (1 - 12 or JAN-DEC) + # β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of the week (0 - 6 or SUN-SAT) + # β”‚ β”‚ β”‚ β”‚ β”‚ + # β”‚ β”‚ β”‚ β”‚ β”‚ + # β”‚ β”‚ β”‚ β”‚ β”‚ + # * * * * * + - cron: '30 1 * * 0' + +jobs: + CodeQL-Build: + # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest + runs-on: ubuntu-latest + + permissions: + # required for all workflows + security-events: write + + # only required for workflows in private repositories + actions: read + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + # Override language selection by uncommenting this and choosing your languages + # with: + # languages: go, javascript, csharp, python, cpp, java, ruby + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below). + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # πŸ“š See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # ✏️ If the Autobuild fails above, remove it and uncomment the following + # three lines and modify them (or add more) to build your code if your + # project uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml new file mode 100644 index 0000000..28112a3 --- /dev/null +++ b/.github/workflows/e2e-test.yml @@ -0,0 +1,49 @@ +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: e2e + +on: + workflow_dispatch: + pull_request: + push: + schedule: + # run e2e test every 4 hours + - cron: 0 */4 * * * + +jobs: + build: + name: Test + runs-on: ubuntu-latest + env: + GO111MODULE: on + steps: + + - name: Set up Go 1.21 + uses: actions/setup-go@v2 + with: + go-version: 1.21 + id: go + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Create e2e test + run: | + echo "...test e2e" diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..7fbcd2e --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,51 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +name: interview golangci-lint +on: + push: + branches: [main] + pull_request: + branches: [main] +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: '1.20' + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Require: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: v1.53 + + # Optional: working directory, useful for monorepos + working-directory: server + + # Optional: golangci-lint command line arguments. + # + # Note: by default the `.golangci.yml` file should be at the root of the repository. + # The location of the configuration file can be changed by using `--config=` + # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional:The mode to install golangci-lint. It can be 'binary' or 'goinstall'. + install-mode: "goinstall" \ No newline at end of file diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml new file mode 100644 index 0000000..4ae5346 --- /dev/null +++ b/.github/workflows/gosec.yml @@ -0,0 +1,44 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# name: Run gosec + +# # gosec is a source code security audit tool for the Go language. It performs a static +# # analysis of the Go code, looking for potential security problems. The main functions of gosec are: +# # 1. Find common security vulnerabilities, such as SQL injection, command injection, and cross-site scripting (XSS). +# # 2. Audit codes according to common security standards and find non-standard codes. +# # 3. Assist the Go language engineer to write safe and reliable code. + +# on: +# push: +# branches: "*" +# pull_request: +# branches: "*" +# paths-ignore: +# - '*.md' +# - '*.yml' +# - '.github' + +# jobs: +# golang-security-action: +# runs-on: ubuntu-latest +# env: +# GO111MODULE: on +# steps: +# - name: Check out code +# uses: actions/checkout@v3 +# - name: Run Gosec Security Scanner +# uses: securego/gosec@master +# with: +# args: ./... \ No newline at end of file diff --git a/.github/workflows/gpt-translate.yml b/.github/workflows/gpt-translate.yml new file mode 100644 index 0000000..810b3c9 --- /dev/null +++ b/.github/workflows/gpt-translate.yml @@ -0,0 +1,37 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# .github/workflows/gpt-translate.yml +name: GPT Translate + +on: + issue_comment: + types: [ created ] + +jobs: + gpt_translate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Run GPT Translate + if: | + contains(github.event.comment.body, '/gpt-translate') || + contains(github.event.comment.body, '/gt') + uses: 3ru/gpt-translate@v1.0 + with: + apikey: ${{ secrets.OPENAI_API4_KEY }} + token: "${{ secrets.BOT_GITHUB_TOKEN }}" \ No newline at end of file diff --git a/.github/workflows/help-comment-issue.yml b/.github/workflows/help-comment-issue.yml new file mode 100644 index 0000000..c785ad0 --- /dev/null +++ b/.github/workflows/help-comment-issue.yml @@ -0,0 +1,35 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Good frist issue add comment +on: + issues: + types: + - labeled +jobs: + add-comment: + if: github.event.label.name == 'help wanted' || github.event.label.name == 'good first issue' + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Add comment + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ github.event.issue.number }} + token: ${{ secrets.BOT_GITHUB_TOKEN }} + body: | + This issue is available for anyone to work on. **Make sure to reference this issue in your pull request.** :sparkles: Thank you for your contribution! :sparkles: + [Join slack πŸ€–](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers. + If you wish to accept this assignment, please leave a comment in the comments section: `/accept`.🎯 diff --git a/.github/workflows/issue-robot.yml b/.github/workflows/issue-robot.yml new file mode 100644 index 0000000..b421a53 --- /dev/null +++ b/.github/workflows/issue-robot.yml @@ -0,0 +1,31 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: 'issue translator' +on: + issue_comment: + types: [created] + issues: + types: [opened] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: usthe/issues-translate-action@v2.7 + with: + # it is not necessary to decide whether you need to modify the issue header content + IS_MODIFY_TITLE: true + BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + # Required, input your bot github token \ No newline at end of file diff --git a/.github/workflows/kubekf.yml b/.github/workflows/kubekf.yml new file mode 100644 index 0000000..ca716c1 --- /dev/null +++ b/.github/workflows/kubekf.yml @@ -0,0 +1,122 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: interview CI + +on: + push: + branches: + - main + paths-ignore: + - "docs/**" + - "README.md" + - "README_zh-CN.md" + - "CONTRIBUTING.md" + pull_request: + branches: + - main + paths-ignore: + - "README.md" + - "README_zh-CN.md" + - "CONTRIBUTING.md" + - "docs/**" + +env: + GO_VERSION: "1.19" + GOLANGCI_VERSION: "v1.50.1" + +jobs: + interview: + name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + environment: + name: interview + + strategy: + matrix: + go_version: ["1.20","1.21"] + os: [ubuntu-latest] + + steps: + - name: Set up Go ${{ matrix.go_version }} + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go_version }} + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Run go modules tidy + run: | + make tidy + + - name: Run go format + run: | + make format + + - name: Generate all necessary files, such as error code files + run: | + make generate + + - name: Check syntax and styling of go sources + run: | + set -e + make lint + + - name: Run unit test and get test coverage + run: | + make cover + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: go + + - name: Build source code for host platform + run: | + sudo make build + echo "Build source code for host platform successfully" + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + + - name: Collect Test Coverage File + uses: actions/upload-artifact@v1.0.0 + with: + name: main-output + path: _output/tmp/coverage.out + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + +# docker-image-tests: +# runs-on: ubuntu-20.04 +# steps: +# - name: Checkout +# uses: actions/checkout@v3 +# with: +# fetch-depth: 0 +# +# - name: Set up Go +# uses: actions/setup-go@v3 +# with: +# go-version: ${{ env.GO_VERSION }} +# +# - name: Run tests +# run: make build +# +# - name: Test docker image +# run: | +# docker build -t interview:ci-build . diff --git a/.github/workflows/link-pr.yml b/.github/workflows/link-pr.yml new file mode 100644 index 0000000..670f657 --- /dev/null +++ b/.github/workflows/link-pr.yml @@ -0,0 +1,60 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: github Rebot for Link check error + +on: + pull_request: + branches: [ main ] + paths: + - '**.md' + - 'docs/**' + push: + branches: [ main ] +# paths: +# - '**.md' +# - 'docs/**' + +jobs: + linkChecker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Link Checker + id: lychee + uses: lycheeverse/lychee-action@v1.7.0 + with: + # For parameter description, see https://github.com/lycheeverse/lychee#commandline-parameters + # Actions Link address -> https://github.com/lycheeverse/lychee-action + # -E, --exclude-all-private Exclude all private IPs from checking. + # -i, --insecure Proceed for server connections considered insecure (invalid TLS) + # -n, --no-progress Do not show progress bar. + # -t, --timeout Website timeout in seconds from connect to response finished [default:20] + # --max-concurrency Maximum number of concurrent network requests [default: 128] + # -a --accept Comma-separated list of accepted status codes for valid links + # docs/.vitepress/dist the site directory to check + # ./*.md all markdown files in the root directory + args: --verbose -E -i --no-progress --exclude-path './CHANGELOG' './**/*.md' + env: + GITHUB_TOKEN: ${{secrets.GH_PAT}} + + - name: Create Issue From File + if: env.lychee_exit_code != 0 + uses: peter-evans/create-issue-from-file@v4 + with: + title: "Bug: Bug reports for links in OpenIM docs" + content-filepath: ./lychee/out.md + labels: kind/documentation, triage/unresolved, report + token: ${{ secrets.BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/project-progress.yml b/.github/workflows/project-progress.yml new file mode 100644 index 0000000..850b213 --- /dev/null +++ b/.github/workflows/project-progress.yml @@ -0,0 +1,33 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +name: Move new issues into Triage + +on: + issues: + types: [opened] + +jobs: + automate-project-columns: + runs-on: ubuntu-latest + steps: + - uses: alex-page/github-project-automation-plus@v0.8.3 + with: + project: interview + column: In Progress + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..0eed809 --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,55 @@ +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - main + # pull_request event is required only for autolabeler + pull_request: + # Only following types are handled by the action, but one can default to all as well + # types: [opened, reopened, synchronize] + # pull_request_target event is required for autolabeler to support PRs from forks + # pull_request_target: + # types: [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write + runs-on: ubuntu-latest + steps: + # (Optional) GitHub Enterprise requires GHE_HOST variable set + #- name: Set GHE_HOST + # run: | + # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV + + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + # with: + # config-name: my-config.yml + # disable-autolabeler: true + env: + GITHUB_TOKEN: ${{ secrets.REDBOT_GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4658c66 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,81 @@ +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: interview Server Release Workflow + +on: + push: + # run only against tags + tags: + - '*' + +permissions: + contents: write + packages: write + issues: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - run: git fetch --force --tags + - uses: actions/setup-go@v4 + with: + go-version: stable + # More assembly might be required: Docker logins, GPG, etc. It all depends + # on your needs. + - uses: goreleaser/goreleaser-action@v4 + with: + # either 'goreleaser' (default) or 'goreleaser-pro': + distribution: goreleaser + version: latest + workdir: . + args: release -f ./build/goreleaser.yaml --rm-dist --clean --release-footer-tmpl=scripts/template/footer.md.tmpl --release-header-tmpl=scripts/template/head.md.tmpl + env: + USERNAME: ${{ github.repository_owner }} + GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + FURY_TOKEN: ${{ secrets.FURY_TOKEN }} + # Your GoReleaser Pro key, if you are using the 'goreleaser-pro' + # distribution: + # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} + + goreleaser-check-pkgs: + runs-on: ubuntu-latest + env: + DOCKER_CLI_EXPERIMENTAL: "enabled" + needs: [ goreleaser ] + if: github.ref == 'refs/heads/main' + strategy: + matrix: + format: [ deb, rpm, apk ] + steps: + - uses: actions/checkout@v3 # v3 + with: + fetch-depth: 0 + - uses: arduino/setup-task@e26d8975574116b0097a1161e0fe16ba75d84c1c # v1 + with: + version: 3.x + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2 + - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: | + ./_output/dist/*.deb + ./_output/dist/*.rpm + ./_output/dist/*.apk + key: ${{ github.ref }} + - run: task goreleaser:test:${{ matrix.format }} \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..f5d6377 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,47 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '0 8 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v5 + with: + repo-token: ${{ secrets.BOT_GITHUB_TOKEN }} + days-before-stale: 60 + days-before-close: 7 + stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.' + stale-pr-message: 'This issue is stale because it has been open 60 days with no activity.' + close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity. You can reopen it if you want.' + stale-pr-label: lifecycle/stale + stale-issue-label: lifecycle/stale + exempt-issue-labels: 'openim' + exempt-pr-labels: 'openim' + exempt-draft-pr: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 0000000..d6e15bf --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,39 @@ +# Copyright Β© 2023 KubeCub open source community. All rights reserved. +# Licensed under the MIT License (the "License"); +# you may not use this file except in compliance with the License. + +# https://github.com/BetaHuhn/repo-file-sync-action +name: Synchronize kubecub public code to other repositories +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Run GitHub File Sync + uses: BetaHuhn/repo-file-sync-action@latest + with: + GH_INSTALLATION_TOKEN: "${{ secrets.BOT_GITHUB_TOKEN }}" + CONFIG_PATH: .github/sync.yml + ORIGINAL_MESSAGE: true + SKIP_PR: true + COMMIT_EACH_FILE: false + COMMIT_BODY: "πŸ€– kubbot to synchronize the warehouse" + GIT_EMAIL: "3293172751ysy@gmail.com" + GIT_USERNAME: "kubbot" + PR_BODY: πŸ‘Œ kubecub provides automated community services + REVIEWERS: | + kubbot + cubxxw + PR_LABELS: | + file-sync + automerge + ASSIGNEES: | + kubbot \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3b735ec..313014b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,28 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# +# Created by https://www.toptal.com/developers/gitignore/api/vim,jetbrains,vscode,git,go,tags,backup,test,emacs +# Edit at https://www.toptal.com/developers/gitignore?templates=vim,jetbrains,vscode,git,go,tags,backup,test,emacs + +### Backup ### +*.bak +*.gho +*.ori +*.orig +*.tmp + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Go ### # Binaries for programs and plugins *.exe *.exe~ @@ -17,5 +39,322 @@ # Dependency directories (remove the comment below to include it) # vendor/ -# Go workspace file -go.work +### Go Patch ### +/vendor/ +/Godeps/ + +### JetBrains ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +.idea/ + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### JetBrains Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +### Tags ### +# Ignore tags created by etags, ctags, gtags (GNU global) and cscope +TAGS +.TAGS +!TAGS/ +tags +.tags +!tags/ +gtags.files +GTAGS +GRTAGS +GPATH +GSYMS +cscope.files +cscope.out +cscope.in.out +cscope.po.out + + +### Test ### +### Ignore all files that could be used to test your code and +### you wouldn't want to push + +# Reference https://en.wikipedia.org/wiki/Metasyntactic_variable + +# Most common +*foo +*bar +*fubar +*foobar +*baz + +# Less common +*qux +*quux +*bongo +*bazola +*ztesch + +# UK, Australia +*wibble +*wobble +*wubble +*flob +*blep +*blah +*boop +*beep + +# Japanese +*hoge +*piyo +*fuga +*hogera +*hogehoge + +# Portugal, Spain +*fulano +*sicrano +*beltrano +*mengano +*perengano +*zutano + +# France, Italy, the Netherlands +*toto +*titi +*tata +*tutu +*pipppo +*pluto +*paperino +*aap +*noot +*mies + +# Other names that would make sense +*tests +*testsdir +*testsfile +*testsfiles +*testdir +*testfile +*testfiles +*testing +*testingdir +*testingfile +*testingfiles +*temp +*tempdir +*tempfile +*tempfiles +*tmp +*tmpdir +*tmpfile +*tmpfiles +*lol + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +# Persistent undo +[._]*.un~ + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive +ltximg/** + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +# /server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +### vscode ### +.vscode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# End of https://www.toptal.com/developers/gitignore/api/vim,jetbrains,vscode,git,go,tags,backup,test + +# Start by iam + +# log +*.log +/server/logs +/server/cmd/dbmigration/logs + +# data +/server/data + +# Output of backend and frontend +/_output +/_debug + +# Misc +.DS_Store +# Add env to web +# *.env +# .env.* +dist + +# files used by the developer +.idea.md +.todo.md +.note.md + +# config files, may contain sensitive information +dist/ + +# interview dev config +server/config.yaml \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..4b09478 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,934 @@ +# Copyright Β© 2023 aicworld open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file contains all available configuration options +# with their default values. + +# options for analysis running +run: + # default concurrency is a available CPU number + concurrency: 4 + + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 5m + + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + + # include test files or not, default is true + tests: true + + # list of build tags, all linters use it. Default is empty list. + build-tags: + - mytag + + # which dirs to skip: issues from them won't be reported; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but default dirs are skipped independently + # from this option's value (see skip-dirs-use-default). + # "/" will be replaced by current OS file path separator to properly work + # on Windows. + skip-dirs: + - util + - .*~ + - api/swagger/docs + - server/docs + + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs-use-default: true + + # which files to skip: they will be analyzed, but issues from them + # won't be reported. Default value is empty list, but there is + # no need to include all autogenerated files, we confidently recognize + # autogenerated files. If it's not please let us know. + # "/" will be replaced by current OS file path separator to properly work + # on Windows. + skip-files: + - ".*\\.my\\.go$" + - _test.go + + # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": + # If invoked with -mod=readonly, the go command is disallowed from the implicit + # automatic updating of go.mod described above. Instead, it fails when any changes + # to go.mod are needed. This setting is most useful to check that go.mod does + # not need updates, such as in a continuous integration and testing system. + # If invoked with -mod=vendor, the go command assumes that the vendor + # directory holds the correct copies of dependencies and ignores + # the dependency descriptions in go.mod. + #modules-download-mode: release|readonly|vendor + + # Allow multiple parallel golangci-lint instances running. + # If false (default) - golangci-lint acquires file lock on start. + allow-parallel-runners: true + + +# output configuration options +output: + # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" + format: colored-line-number + + # print lines of code with issue, default is true + print-issued-lines: true + + # print linter name in the end of issue text, default is true + print-linter-name: true + + # make issues output unique by line, default is true + uniq-by-line: true + + # add a prefix to the output file references; default is no prefix + path-prefix: "" + + # sorts results by: filepath, line and column + sort-results: true + +# all available settings of specific linters +linters-settings: + bidichk: + # The following configurations check for all mentioned invisible unicode + # runes. It can be omitted because all runes are enabled by default. + left-to-right-embedding: true + right-to-left-embedding: true + pop-directional-formatting: true + left-to-right-override: true + right-to-left-override: true + left-to-right-isolate: true + right-to-left-isolate: true + first-strong-isolate: true + pop-directional-isolate: true + dogsled: + # checks assignments with too many blank identifiers; default is 2 + max-blank-identifiers: 2 + dupl: + # tokens count to trigger issue, 150 by default + threshold: 200 + errcheck: + # report about not checking of errors in type assertions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + + # [deprecated] comma-separated list of pairs of the form pkg:regex + # the regex is used to ignore names within pkg. (default "fmt:.*"). + # see https://github.com/kisielk/errcheck#the-deprecated-method for details + #ignore: GenMarkdownTree,os:.*,BindPFlags,WriteTo,Help + #ignore: (os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv + + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + #exclude: errcheck.txt + + errorlint: + # Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats + errorf: true + # Check for plain type assertions and type switches + asserts: true + # Check for plain error comparisons + comparison: true + + exhaustive: + # check switch statements in generated files also + check-generated: false + # indicates that switch statements are to be considered exhaustive if a + # 'default' case is present, even if all enum members aren't listed in the + # switch + default-signifies-exhaustive: false + # enum members matching the supplied regex do not have to be listed in + # switch statements to satisfy exhaustiveness + ignore-enum-members: "" + # consider enums only in package scopes, not in inner scopes + package-scope-only: false + exhaustivestruct: + struct-patterns: + - '*.Test' + - '*.Test2' + - '*.Embedded' + - '*.External' + + # forbidigo: + # # Forbid the following identifiers (identifiers are written using regexp): + # forbid: + # - ^print.*$ + # - 'fmt\.Print.*' + # - fmt.Println.* # too much log noise + # - ginkgo\\.F.* # these are used just for local development + # # Exclude godoc examples from forbidigo checks. Default is true. + # exclude_godoc_examples: false + funlen: + lines: 150 + statements: 50 + gci: + # put imports beginning with prefix after 3rd-party packages; + # only support one prefix + # if not set, use goimports.local-prefixes + prefix: github.com/aicworld/interview + gocognit: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 30 + goconst: + # minimal length of string constant, 3 by default + min-len: 3 + # minimal occurrences count to trigger, 3 by default + min-occurrences: 3 + # ignore test files, false by default + ignore-tests: false + # look for existing constants matching the values, true by default + match-constant: true + # search also for duplicated numbers, false by default + numbers: false + # minimum value, only works with goconst.numbers, 3 by default + min: 3 + # maximum value, only works with goconst.numbers, 3 by default + max: 3 + # ignore when constant is not used as function argument, true by default + ignore-calls: true + + gocritic: + # Which checks should be enabled; can't be combined with 'disabled-checks'; + # See https://go-critic.github.io/overview#checks-overview + # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` + # By default list of stable checks is used. + enabled-checks: + #- rangeValCopy + - nestingreduce + - truncatecmp + - unnamedresult + - ruleguard + + # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty + disabled-checks: + - regexpMust + - ifElseChain + #- exitAfterDefer + + # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. + # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". + enabled-tags: + - performance + disabled-tags: + - experimental + + # Settings passed to gocritic. + # The settings key is the name of a supported gocritic checker. + # The list of supported checkers can be find in https://go-critic.github.io/overview. + settings: + captLocal: # must be valid enabled check name + # whether to restrict checker to params only (default true) + paramsOnly: true + elseif: + # whether to skip balanced if-else pairs (default true) + skipBalanced: true + hugeParam: + # size in bytes that makes the warning trigger (default 80) + sizeThreshold: 80 + nestingReduce: + # min number of statements inside a branch to trigger a warning (default 5) + bodyWidth: 5 + rangeExprCopy: + # size in bytes that makes the warning trigger (default 512) + sizeThreshold: 512 + # whether to check test functions (default true) + skipTestFuncs: true + rangeValCopy: + # size in bytes that makes the warning trigger (default 128) + sizeThreshold: 32 + # whether to check test functions (default true) + skipTestFuncs: true + ruleguard: + # path to a gorules file for the ruleguard checker + rules: '' + truncateCmp: + # whether to skip int/uint/uintptr types (default true) + skipArchDependent: true + underef: + # whether to skip (*x).method() calls where x is a pointer receiver (default true) + skipRecvDeref: true + unnamedResult: + # whether to check exported functions + checkExported: true + gocyclo: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 30 + cyclop: + # the maximal code complexity to report + max-complexity: 50 + # the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0) + package-average: 0.0 + # should ignore tests (default false) + skip-tests: false + godot: + # comments to be checked: `declarations`, `toplevel`, or `all` + scope: declarations + # list of regexps for excluding particular comment lines from check + exclude: + # example: exclude comments which contain numbers + # - '[0-9]+' + # check that each sentence starts with a capital letter + capital: false + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + #- TODO + - BUG + - FIXME + #- NOTE + - OPTIMIZE # marks code that should be optimized before merging + - HACK # marks hack-arounds that should be removed before merging + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + + gofumpt: + # Select the Go version to target. The default is `1.18`. + lang-version: "1.20" + + # Choose whether or not to use the extra rules that are disabled + # by default + extra-rules: false + + goheader: + values: + const: + # define here const type values in format k:v, for example: + # COMPANY: MY COMPANY + regexp: + # define here regexp type values, for example + # AUTHOR: .*@mycompany\.com + template: # |- + # put here copyright header template for source code files, for example: + # Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time. + # + # {{ AUTHOR }} {{ COMPANY }} {{ YEAR }} + # SPDX-License-Identifier: Apache-2.0 + + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at: + + # http://www.apache.org/licenses/LICENSE-2.0 + + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + template-path: + # also as alternative of directive 'template' you may put the path to file with the template source + goimports: + # put imports beginning with prefix after 3rd-party packages; + # it's a comma-separated list of prefixes + local-prefixes: github.com/aicworld/interview + golint: + # minimal confidence for issues, default is 0.8 + min-confidence: 0.9 + gomnd: + settings: + mnd: + # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. + checks: argument,case,condition,operation,return,assign + # ignored-numbers: 1000 + # ignored-files: magic_.*.go + # ignored-functions: math.* + gomoddirectives: + # Allow local `replace` directives. Default is false. + replace-local: true + # List of allowed `replace` directives. Default is empty. + replace-allow-list: + - google.golang.org/grpc + + # Allow to not explain why the version has been retracted in the `retract` directives. Default is false. + retract-allow-no-explanation: false + # Forbid the use of the `exclude` directives. Default is false. + exclude-forbidden: false + gomodguard: + allowed: + modules: + - gorm.io/gen # List of allowed modules + - gorm.io/gorm + - gorm.io/driver/mysql + - k8s.io/klog + # - gopkg.in/yaml.v2 + domains: # List of allowed module domains + - google.golang.org + - gopkg.in + - golang.org + - github.com + - go.uber.org + - go.etcd.io + blocked: + versions: + - github.com/MakeNowJust/heredoc: + version: "> 2.0.9" + reason: "use the latest version" + local_replace_directives: false # Set to true to raise lint issues for packages that are loaded from a local path via replace directive + + gosec: + # To select a subset of rules to run. + # Available rules: https://github.com/securego/gosec#available-rules + includes: + - G401 + - G306 + - G101 + # To specify a set of rules to explicitly exclude. + # Available rules: https://github.com/securego/gosec#available-rules + excludes: + - G204 + # Exclude generated files + exclude-generated: true + # Filter out the issues with a lower severity than the given value. Valid options are: low, medium, high. + severity: "low" + # Filter out the issues with a lower confidence than the given value. Valid options are: low, medium, high. + confidence: "low" + # To specify the configuration of rules. + # The configuration of rules is not fully documented by gosec: + # https://github.com/securego/gosec#configuration + # https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102 + config: + G306: "0600" + G101: + pattern: "(?i)example" + ignore_entropy: false + entropy_threshold: "80.0" + per_char_threshold: "3.0" + truncate: "32" + + gosimple: + # Select the Go version to target. The default is '1.13'. + go: "1.20" + # https://staticcheck.io/docs/options#checks + checks: [ "all" ] + + govet: + # report about shadowed variables + check-shadowing: true + + # settings per analyzer + settings: + printf: # analyzer name, run `go tool vet help` to see all analyzers + funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + + # enable or disable analyzers by name + enable: + - atomicalign + enable-all: false + disable: + - shadow + disable-all: false + # depguard: + # list-type: blacklist + # include-go-root: false + # packages: + # - github.com/Sirupsen/logrus + # packages-with-error-message: + # # specify an error message to output when a blacklisted package is used + # - github.com/Sirupsen/logrus: "logging is allowed only by logutils.Log" + ifshort: + # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax. + # Has higher priority than max-decl-chars. + max-decl-lines: 1 + # Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax. + max-decl-chars: 30 + + importas: + # if set to `true`, force to use alias. + no-unaliased: true + # List of aliases + alias: + # using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package + - pkg: knative.dev/serving/pkg/apis/serving/v1 + alias: servingv1 + # using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package + - pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1 + alias: autoscalingv1alpha1 + # You can specify the package path by regular expression, + # and alias by regular expression expansion syntax like below. + # see https://github.com/julz/importas#use-regular-expression for details + - pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+) + alias: $1$2 + # using `jwt` alias for `github.com/appleboy/gin-jwt/v2` package + jwt: github.com/appleboy/gin-jwt/v2 + + ireturn: + # ireturn allows using `allow` and `reject` settings at the same time. + # Both settings are lists of the keywords and regular expressions matched to interface or package names. + # keywords: + # - `empty` for `interface{}` + # - `error` for errors + # - `stdlib` for standard library + # - `anon` for anonymous interfaces + + # By default, it allows using errors, empty interfaces, anonymous interfaces, + # and interfaces provided by the standard library. + allow: + - anon + - error + - empty + - stdlib + # You can specify idiomatic endings for interface + - (or|er)$ + + # Reject patterns + reject: + - github.com\/user\/package\/v4\.Type + + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 240 + # tab width in spaces. Default to 1. + tab-width: 4 + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - someword + nakedret: + # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + max-func-lines: 30 + + nestif: + # minimal complexity of if statements to report, 5 by default + min-complexity: 4 + + nilnil: + # By default, nilnil checks all returned types below. + checked-types: + - ptr + - func + - iface + - map + - chan + + nlreturn: + # size of the block (including return statement that is still "OK") + # so no return split required. + block-size: 1 + + nolintlint: + # Disable to ensure that all nolint directives actually have an effect. Default is true. + allow-unused: false + # Disable to ensure that nolint directives don't have a leading space. Default is true. + allow-leading-space: true + # Exclude following linters from requiring an explanation. Default is []. + allow-no-explanation: [ ] + # Enable to require an explanation of nonzero length after each nolint directive. Default is false. + require-explanation: false + # Enable to require nolint directives to mention the specific linter being suppressed. Default is false. + require-specific: true + + prealloc: + # XXX: we don't recommend using this linter before doing performance profiling. + # For most programs usage of prealloc will be a premature optimization. + + # Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. + # True by default. + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + + promlinter: + # Promlinter cannot infer all metrics name in static analysis. + # Enable strict mode will also include the errors caused by failing to parse the args. + strict: false + # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage. + disabled-linters: + # - "Help" + # - "MetricUnits" + # - "Counter" + # - "HistogramSummaryReserved" + # - "MetricTypeInName" + # - "ReservedChars" + # - "CamelCase" + # - "lintUnitAbbreviations" + + predeclared: + # comma-separated list of predeclared identifiers to not report on + ignore: "" + # include method names and field names (i.e., qualified names) in checks + q: false + rowserrcheck: + packages: + - github.com/jmoiron/sqlx + revive: + # see https://github.com/mgechev/revive#available-rules for details. + ignore-generated-header: true + severity: warning + rules: + - name: indent-error-flow + severity: warning + staticcheck: + # Select the Go version to target. The default is '1.13'. + go: "1.16" + # https://staticcheck.io/docs/options#checks + checks: [ "all" ] + + stylecheck: + # Select the Go version to target. The default is '1.13'. + go: "1.16" + + # https://staticcheck.io/docs/options#checks + checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ] + # https://staticcheck.io/docs/options#dot_import_whitelist + dot-import-whitelist: + - fmt + # https://staticcheck.io/docs/options#initialisms + initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ] + # https://staticcheck.io/docs/options#http_status_code_whitelist + http-status-code-whitelist: [ "200", "400", "404", "500" ] + + + tagliatelle: + # check the struck tag name case + case: + # use the struct field name to check the name of the struct tag + use-field-name: true + rules: + # any struct tag type can be used. + # support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower` + json: camel + yaml: camel + xml: camel + bson: camel + avro: snake + mapstructure: kebab + + testpackage: + # regexp pattern to skip files + skip-regexp: (id|export|internal)_test\.go + thelper: + # The following configurations enable all checks. It can be omitted because all checks are enabled by default. + # You can enable only required checks deleting unnecessary checks. + test: + first: true + name: true + begin: true + benchmark: + first: true + name: true + begin: true + tb: + first: true + name: true + begin: true + + tenv: + # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures. + # By default, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked. + all: false + + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + unused: + # treat code as a program (not a library) and report unused exported identifiers; default is false. + # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find funcs usages. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + + wrapcheck: + # An array of strings that specify substrings of signatures to ignore. + # If this set, it will override the default set of ignored signatures. + # See https://github.com/tomarrell/wrapcheck#configuration for more information. + ignoreSigs: + - .Errorf( + - errors.New( + - errors.Unwrap( + - .Wrap( + - .Wrapf( + - .WithMessage( + - .WithMessagef( + - .WithStack( + ignorePackageGlobs: + - encoding/* + - github.com/pkg/* + + wsl: + # If true append is only allowed to be cuddled if appending value is + # matching variables, fields or types on line above. Default is true. + strict-append: true + # Allow calls and assignments to be cuddled as long as the lines have any + # matching variables, fields or types. Default is true. + allow-assign-and-call: true + # Allow assignments to be cuddled with anything. Default is false. + allow-assign-and-anything: false + # Allow multiline assignments to be cuddled. Default is true. + allow-multiline-assign: true + # Allow declarations (var) to be cuddled. + allow-cuddle-declarations: false + # Allow trailing comments in ending of blocks + allow-trailing-comment: false + # Force newlines in end of case at this limit (0 = never). + force-case-trailing-whitespace: 0 + # Force cuddling of err checks with err var assignment + force-err-cuddling: false + # Allow leading comments to be separated with empty liens + allow-separated-leading-comment: false + makezero: + # Allow only slices initialized with a length of zero. Default is false. + always: false + + + # The custom section can be used to define linter plugins to be loaded at runtime. See README doc + # for more info. + #custom: + # Each custom linter should have a unique name. + #example: + # The path to the plugin *.so. Can be absolute or local. Required for each custom linter + #path: /path/to/example.so + # The description of the linter. Optional, just for documentation purposes. + #description: This is an example usage of a plugin linter. + # Intended to point to the repo location of the linter. Optional, just for documentation purposes. + #original-url: github.com/golangci/example-linter + +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + # enable-all: true + disable-all: true + enable: + - typecheck + - asciicheck + - bodyclose + - cyclop + - deadcode + # - depguard + - dogsled + - dupl + - durationcheck + - errcheck + - errorlint + - exhaustive + - exportloopref + # - forbidigo + - funlen + # - gci + # - gochecknoinits + - gocognit + - goconst + - gocyclo + - godot + - godox + - gofmt + - gofumpt + - goheader + - goimports + - gomoddirectives + - gomodguard + - goprintffuncname + - gosec + - gosimple + - govet + - ifshort + - importas + - ineffassign + - lll + - makezero + - misspell + - nakedret + - nestif + - nilerr + - nlreturn + - noctx + - nolintlint + - paralleltest + - prealloc + - predeclared + - promlinter + - revive + - rowserrcheck + - sqlclosecheck + - staticcheck + - structcheck + - stylecheck + - thelper + - tparallel + - unconvert + - unparam + - unused + - varcheck + - wastedassign + - whitespace + - bidichk + - wastedassign + - golint + - execinquery + - nosprintfhostport + - grouper + - decorder + - errchkjson + - maintidx + #- containedctx + #- tagliatelle + #- nonamedreturns + #- nilnil + #- tenv + #- varnamelen + #- contextcheck + #- errname + #- ForceTypeAssert + #- nilassign + fast: false + +issues: + # List of regexps of issue texts to exclude, empty list by default. + # But independently from this option we use default exclude patterns, + # it can be disabled by `exclude-use-default: false`. To list all + # excluded by default patterns execute `golangci-lint run --help` + exclude: + - tools/.* + - test/.* + - third_party/.* + + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + - linters: + - golint + path: (internal/api/.*)\.go # exclude golint for internal/api/... files + + - linters: + - revive + path: (log/.*)\.go + + - linters: + - wrapcheck + path: (cmd/.*|pkg/.*)\.go + + - linters: + - typecheck + #path: (pkg/storage/.*)\.go + path: (internal/.*|pkg/.*)\.go + + - path: (cmd/.*|test/.*|tools/.*|internal/pump/pumps/.*)\.go + linters: + - forbidigo + + - path: (cmd/[a-z]*/.*|store/.*)\.go + linters: + - dupl + + - linters: + - gocritic + text: (hugeParam:|rangeValCopy:) + + - path: (cmd/[a-z]*/.*)\.go + linters: + - lll + + - path: (validator/.*|code/.*|validator/.*|watcher/watcher/.*) + linters: + - gochecknoinits + + - path: (internal/.*/options|internal/pump|pkg/log/options.go|internal/authzserver|tools/) + linters: + - tagliatelle + + - path: (pkg/app/.*)\.go + linters: + - deadcode + - unused + - varcheck + - forbidigo + + # Exclude some staticcheck messages + - linters: + - staticcheck + text: "SA9003:" + + # Exclude lll issues for long lines with go:generate + - linters: + - lll + source: "^//go:generate " + + # Independently from option `exclude` we use default exclude patterns, + # it can be disabled by this option. To list all + # excluded by default patterns execute `golangci-lint run --help`. + # Default value for this option is true. + exclude-use-default: true + + # The default value is false. If set to true exclude and exclude-rules + # regular expressions become case sensitive. + exclude-case-sensitive: false + + # The list of ids of default excludes to include or disable. By default it's empty. + include: + - EXC0002 # disable excluding of issues about comments from golint + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-issues-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 + + # Show only new issues: if there are unstaged changes or untracked files, + # only those changes are analyzed, else only changes in HEAD~ are analyzed. + # It's a super-useful option for integration of golangci-lint into existing + # large codebase. It's not practical to fix all existing issues at the moment + # of integration: much better don't allow issues in new code. + # Default is false. + new: false + + # Show only new issues created after git revision `REV` + # new-from-rev: REV + + # Show only new issues created in git patch with set file path. + #new-from-patch: path/to/patch/file + + # Fix found issues (if it's supported by the linter) + fix: true + +severity: + # Default value is empty string. + # Set the default severity for issues. If severity rules are defined and the issues + # do not match or no severity is provided to the rule this will be the default + # severity applied. Severities should match the supported severity names of the + # selected out format. + # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity + # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity + # - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + default-severity: error + + # The default value is false. + # If set to true severity-rules regular expressions become case sensitive. + case-sensitive: false + + # Default value is empty list. + # When a list of severity rules are provided, severity information will be added to lint + # issues. Severity rules have the same filtering capability as exclude rules except you + # are allowed to specify one matcher per severity rule. + # Only affects out formats that support setting severity information. + rules: + - linters: + - dupl + severity: info \ No newline at end of file diff --git a/CHANGELOG/.chglog/CHANGELOG.tpl.md b/CHANGELOG/.chglog/CHANGELOG.tpl.md new file mode 100644 index 0000000..4569e5e --- /dev/null +++ b/CHANGELOG/.chglog/CHANGELOG.tpl.md @@ -0,0 +1,62 @@ +# Version logging for interview + + + + + +{{ if .Versions -}} + +## [Unreleased] + +{{ if .Unreleased.CommitGroups -}} +{{ range .Unreleased.CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{ range .Versions }} + +## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} +{{ range .CommitGroups -}} +### {{ .Title }} +{{ range .Commits -}} +- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} +{{ end }} +{{ end -}} + +{{- if .RevertCommits -}} +### Reverts +{{ range .RevertCommits -}} +- {{ .Revert.Header }} +{{ end }} +{{ end -}} + +{{- if .MergeCommits -}} +### Pull Requests +{{ range .MergeCommits -}} +- {{ .Header }} +{{ end }} +{{ end -}} + +{{- if .NoteGroups -}} +{{ range .NoteGroups -}} +### {{ .Title }} +{{ range .Notes }} +{{ .Body }} +{{ end }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- if .Versions }} +[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD +{{ range .Versions -}} +{{ if .Tag.Previous -}} +[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} +{{ end -}} +{{ end -}} +{{ end -}} \ No newline at end of file diff --git a/CHANGELOG/.chglog/config.yml b/CHANGELOG/.chglog/config.yml new file mode 100644 index 0000000..ed151e3 --- /dev/null +++ b/CHANGELOG/.chglog/config.yml @@ -0,0 +1,66 @@ +bin: git +style: github +template: CHANGELOG.tpl.md +info: + title: CHANGELOG + repository_url: https://github.com/aicworld/interview +options: + tag_filter_pattern: '^v' + sort: "date" + + commits: + filters: + Type: + - feat + - fix + - perf + - refactor + - docs + - test + - chore + - ci + - build + + commit_groups: + group_by: Type + sort_by: Title + title_order: + - feat + - fix + - perf + - refactor + - docs + - test + - chore + - ci + - build + + header: + pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$" + pattern_maps: + - Type + - Scope + - Subject + + issues: + prefix: + - # + + refs: + actions: + - Closes + - Fixes + + merges: + pattern: "^Merge branch '(\\w+)'$" + pattern_maps: + - Source + + reverts: + pattern: "^Revert \"([\\s\\S]*)\"$" + pattern_maps: + - Header + + notes: + keywords: + - BREAKING CHANGE \ No newline at end of file diff --git a/CHANGELOG/CHANGELOG-0.1.md b/CHANGELOG/CHANGELOG-0.1.md new file mode 100644 index 0000000..f37b07f --- /dev/null +++ b/CHANGELOG/CHANGELOG-0.1.md @@ -0,0 +1,72 @@ + +# Version logging for interview + + + + + + +## [Unreleased] + +### Docs +- design interview docs ([#68](https://github.com/aicworld/interview/issues/68)) +- fix markdown link ([#65](https://github.com/aicworld/interview/issues/65)) +- fix markdown link ([#64](https://github.com/aicworld/interview/issues/64)) +- fix markdown link ([#63](https://github.com/aicworld/interview/issues/63)) + +### Feat +- add COLOR_SUFFIX=033[0m # End all colors and special effects +- Add register api with dao cmd. ([#73](https://github.com/aicworld/interview/issues/73)) +- add logo file of Xx design +- add logo file of Xx design +- add logo file of Xx design +- add roadmap file +- add proposal file +- modify issue-specification.md +- add issue specification +- issue20 +- add actions file +- **main:** optimize deployment ([#36](https://github.com/aicworld/interview/issues/36)) +- **main:** optimize deployment ([#36](https://github.com/aicworld/interview/issues/36)) +- **main:** release script file ([#52](https://github.com/aicworld/interview/issues/52)) + +### Fix +- docs link + + + +## v0.1.0 - 2023-07-05 +### Docs +- update code owners file ([#50](https://github.com/aicworld/interview/issues/50)) +- update README.md ([#43](https://github.com/aicworld/interview/issues/43)) +- update readme and readme-zh ([#35](https://github.com/aicworld/interview/issues/35)) + +### Feat +- Add hook interceptor & add cmd & some fix ([#24](https://github.com/aicworld/interview/issues/24)) +- Support auto-signature. ([#49](https://github.com/aicworld/interview/issues/49)) +- Add callback api. ([#45](https://github.com/aicworld/interview/issues/45)) +- add a component to support rate limt control ([#29](https://github.com/aicworld/interview/issues/29)) +- add prettier and eslint ([#18](https://github.com/aicworld/interview/issues/18)) ([#30](https://github.com/aicworld/interview/issues/30)) +- add script license ([#17](https://github.com/aicworld/interview/issues/17)) +- Support send code with email. ([#15](https://github.com/aicworld/interview/issues/15)) +- init plugin project. ([#14](https://github.com/aicworld/interview/issues/14)) +- enhance automated review for codeowners ([#11](https://github.com/aicworld/interview/issues/11)) +- init server project ([#5](https://github.com/aicworld/interview/issues/5)) +- **main:** add swagger api make file ([#51](https://github.com/aicworld/interview/issues/51)) +- **main:** unit test makefile ([#56](https://github.com/aicworld/interview/issues/56)) +- **main:** initialize the interview architecture + +### Fix +- Fix doc links. ([#41](https://github.com/aicworld/interview/issues/41)) +- Fix golang ci piplines and docs. ([#39](https://github.com/aicworld/interview/issues/39)) +- cicd err tidy mod +- golang ci +- make fix ([#33](https://github.com/aicworld/interview/issues/33)) +- Fix CONTRIBUTING. ([#28](https://github.com/aicworld/interview/issues/28)) +- codeql token +- **main:** fix cicd actions +- **main:** optimize actions +- **main:** optimize actions + + +[Unreleased]: https://github.com/aicworld/interview/compare/v0.1.0...HEAD diff --git a/CHANGELOG/CHANGELOG.md b/CHANGELOG/CHANGELOG.md new file mode 100644 index 0000000..3f6193b --- /dev/null +++ b/CHANGELOG/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +All notable changes to this project will be documented in this file. + ++ [https://github.com/aicworld/interview/releases](https://github.com/aicworld/interview/releases) + +## command + +```bash +git-chglog --tag-filter-pattern 'v2.0.*' -o CHANGELOG-2.0.md +``` + +## create next tag + +```bash +git-chglog --next-tag 2.0.0 -o CHANGELOG.md +git commit -am "release 2.0.0" +git tag 2.0.0 +``` + +## Release version logs + ++ [OpenIM CHANGELOG-V0.1](CHANGELOG-0.1.md) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5bbda1b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,446 @@ +# Contributing to interview + +So, you want to hack on interview? Yay! + +First of all, thank you for considering contributing to our project! We appreciate your time and effort, and we value any contribution, whether it's reporting a bug, suggesting a new feature, or submitting a pull request. + +This document provides guidelines and best practices to help you contribute effectively. + +## πŸ“‡Topics + +- [Contributing to interview](#contributing-to-interview) + - [πŸ“‡Topics](#topics) + - [What we expect of you](#what-we-expect-of-you) + - [Code of Conduct](#code-of-conduct) + - [Code and doc contribution](#code-and-doc-contribution) + - [Where should I start?](#where-should-i-start) + - [Design documents](#design-documents) + - [Getting Started](#getting-started) + - [Style and Specification](#style-and-specification) + - [Reporting security issues](#reporting-security-issues) + - [Reporting general issues](#reporting-general-issues) + - [Commit Rules](#commit-rules) + - [PR Description](#pr-description) + - [CI actions](#ci-actions) + - [Docs Contribution](#docs-contribution) + - [Engage to help anything](#engage-to-help-anything) + - [Release version](#release-version) + - [Contact Us](#contact-us) + + + +## What we expect of you + +We hope that anyone can join interview , even if you are a student, writer, translator + +Please meet the minimum version of the Go language published in [go.mod](./server/go.mod). If you want to manage the Go language version, we provide tools to install [gvm](https://github.com/moovweb/gvm) in our [Makefile](./Makefile) + +You'd better use Linux as the development environment, Linux with [Makefile](./Makefile) can help you quickly build and test interview project. + +If you are familiar with [Makefile](./Makefile) , you can easily see the clever design of the interview Makefile. Storing the necessary tools such as golangci in the `/tools` directory can avoid some tool version issues. + +The [Makefile](./Makefile) is for every developer, even if you don't know how to use the Makefile tool, don't worry, we provide two great commands to get you up to speed with the Makefile architecture, `make help` and `make help-all`, it can reduce problems of the developing environment. + + + +## Code of Conduct + +#### Code and doc contribution + +Every action to make project interview better is encouraged. On GitHub, every improvement for interview could be via a [PR](https://github.com/aicworld/interview/pulls) (short for pull request). + ++ If you find a typo, try to fix it! ++ If you find a bug, try to fix it! ++ If you find some redundant codes, try to remove them! ++ If you find some test cases missing, try to add them! ++ If you could enhance a feature, please **DO NOT** hesitate! ++ If you find code implicit, try to add comments to make it clear! ++ If you find code ugly, try to refactor that! ++ If you can help to improve documents, it could not be better! ++ If you find document incorrect, just do it and fix that! ++ ... + +#### Where should I start? + +Getting good at GitHub is the first step, we have a [list of labes](https://github.com/aicworld/interview/labels) and reading some of the [common tags](https://github.com/aicworld/interview/labels?sort=count-desc) helps us get involved in the community quickly.GitHub allows you to filter out types of issues and pull requests, which helps you discover items in need of triaging. This table includes some predetermined searches for convenience: + +| Search | What it sorts | +| ------------------------------------------------------------ | ------------------------------------------------------- | +| [created-asc](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Acreated-asc) | Untriaged issues by age | +| [needs-triage](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+no%3Alabel) | Issues that need to be assigned to a Labels | +| [`is:open is:issue`](https://github.com/aicworld/interview/issues?q=is%3Aopen+is%3Aissue+sort%3Aupdated-desc) | Newest incoming issues | +| [comments-desc](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc) | Busiest untriaged issues, sorted by # of comments | +| [comments-asc](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-asc) | Issues that need more attention, based on # of comments | + +We suggest preparing your triage by filtering out the oldest, unlabelled issues and pull requests first. + +1. If you are new to the project, don't know how to contribute interview, please check out the [good first issue](https://github.com/aicworld/interview/issues?q=is%3Aopen+label%3A"good+first+issue"+sort%3Aupdated-desc) label and [help wanted](https://github.com/aicworld/interview/issues?q=is%3Aopen+is%3Aissue+label%3A"help+wanted"+sort%3Aupdated-desc). +2. You should be good at filtering the interview issue tags and finding the ones you like, such as [RFC](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) for big initiatives, features for [feature](https://github.com/aicworld/interview/issues?q=is%3Aissue+label%3Akind%2Ffeature+sort%3Aupdated-desc+) proposals, and [bug](https://github.com/aicworld/interview/issues?q=is%3Aissue+label%3Akind%2Fbug+sort%3Aupdated-desc+) fixes. +3. If you are looking for something to work on, check out our [open issues](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). +4. If you have an idea for a new feature, please [open an issue](https://github.com/aicworld/interview/issues/new/choose), and we can discuss it. + +> **Note** +> Reply to `/assign` or `/assign @yourself` with a question you wish to resolve, and we'll assign the question to you and your name will be listed under `Assignees` + + + +#### Design documents + +For any substantial design, there should be a well-crafted design document. This document is not just a simple record, but also a detailed description and manifestation, which can help team members better understand the design thinking and grasp the design direction. In the process of writing the design document, we can choose to use tools such as `Google Docs` or `Notion`, and even mark **RFC** in [issues](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) or [discussions](https://github.com/aicworld/interview/discussions) for better collaboration. Of course, after completing the design document, we should also add it to our [Shared Drive](https://drive.google.com/drive/) and notify the appropriate working group to let everyone know of its existence. Only by doing so can we maximize the effectiveness of the design document and provide strong support for the smooth progress of the project. + +Anybody can access the shared Drive for reading. To get access to comment. Once you've done that, head to the [shared Drive](https://drive.google.com/) and behold all the docs. + +In addition to that, we'd love to invite you to [Join Our Slack](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) where you can play with your imagination, tell us what you're working on, and get a quick response. + +When documenting a new design, we recommend a 2-step approach: + +1. Use the short-form **RFC** template to outline your ideas and get early feedback. +2. Once you have received sufficient feedback and consensus, you may use the **longer-form design doc template** to specify and discuss your design in more details. + +**In order to contribute a feature to interview you'll need to go through the following steps:** + ++ Discuss your idea with the appropriate [working groups](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) on the working group's Slack channel. ++ Once there is general agreement that the feature is useful, create a GitHub issue to track the discussion. The issue should include information about the requirements and use cases that it is trying to address. ++ Include a discussion of the proposed design and technical details of the implementation in the issue. + +But keep in mind that there is no guarantee of it being accepted and so it is usually best to get agreement on the **idea/design** before time is spent coding it. However, sometimes seeing the exact code change can help focus discussions, so the choice is up to you. + + + +## Getting Started + +> **Note** +> +> A simple example allows you to quickly contribute your first **PR** to interview. +> To propose PR for the interview item, we assume you have registered a GitHub ID. Then you could finish the preparation in the following steps: + +1. **Fork** the repository(interview) + +2. **CLONE** your own repository to master locally. Use `git clone https://github.com//interview.git` to clone repository to your local machine. Then you can create new branches to finish the change you wish to make. + +3. **Set Remote** upstream to be `https://github.com/aicworld/interview.git` using the following two commands: + + ```bash + ❯ git remote add upstream https://github.com/aicworld/interview.git + ❯ git remote set-url --push upstream no-pushing + ``` + + With this remote setting, you can check your **git remote configuration** like this: + + ```go + ❯ git remote -v + origin https://github.com//interview.git (fetch) + origin https://github.com//interview.git (push) + upstream https://github.com/aicworld/interview.git (fetch) + upstream no-pushing (push) + ``` + + Adding this, we can easily synchronize local branches with upstream branches. + +4. Create a new branch for your changes (use a descriptive name, such as `fix/bug-123` or `feature/add-new-xxx` and `release/xxx`). + + ```bash + ❯ cd interview + ❯ git fetch upstream + ❯ git checkout -b fix/bug- + ``` + + > **Note** + > + > Please don't use `git pull` instead of the above `fetch` and `rebase`. Since `git pull` executes a merge, it creates merge commits. These make the commit history messy and violate the principle that commits ought to be individually understandable and useful. + > + > You might also consider changing your `.git/config` file via `git config branch.autoSetupRebase always` to change the behavior of `git pull`, or another non-merge option such as `git pull --rebase`. + + Create a new branch: + + ```bash + ❯ git checkout -b + ``` + + Make any change on the `new-branch` then use [Makefile](./Makefile) **build** and **test** your codes. + +5. **Commit your changes** to your local branch, lint before committing and commit with sign-off + + ```bash + ❯ git rebase upstream/main + ❯ make lint # golangci-lint run -c .golangci.yml + ❯ git add -A # add changes to staging + ❯ git commit -a -s -m "fix: message for your changes" # -s adds a Signed-off-by trailer + ``` + +6. **Push your branch** to your forked repository, it is recommended to have only one commit for a **PR**. + + ```bash + # sync up with upstream + ❯ git fetch upstream + ❯ git rebase upstream/main + ❯ git rebase -i # rebase with interactive mode to `squash` your commits into a single one + ❯ git push # push to the remote repository, if it's a first time push, run git push --set-upstream origin + ``` + + You can also use `git commit -s --amend && git push -f` to update modifications on the previous commit. + + If you have developed multiple features in the same branch, you should create PR separately by rebasing to the main branch between each push: + + ```bash + # create new branch, for example git checkout -b feature/infra + ❯ git checkout -b + # update some code, feature1 + ❯ git add -A + ❯ git commit -s -m "feat: feature one" + ❯ git push # if it's first time push, run git push --set-upstream origin + # then create pull request, and merge + # update some new feature, feature2, rebase main branch first. + ❯ git rebase upstream/main # rebase the current branch to upstream/main branch + ❯ git add -A + ❯ git commit -s -m "feat: feature two" + # then create pull request, and merge + ``` + +7. **Open a pull request** to `aicworld/interview:main` + + It is recommended to review your changes before filing a pull request. Check if your code doesn't conflict with the main branch and no redundant code is included. + + + +## Style and Specification + +We divide the problem into security and general problems: + +#### Reporting security issues + +Security issues are always treated seriously. As our usual principle, we discourage anyone to spread security issues. If you find a security issue of interview, please do not discuss it in public and even do not open a public issue. + +Instead we encourage you to send us a private email to {email} to report this. + +#### Reporting general issues + +To be honest, we regard every user of interviewas a very kind contributor. After experiencing interview, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/aicworld/interview/issues/new/choose). + +Since we collaborate project interview in a distributed way, we appreciate **WELL-WRITTEN**, **DETAILED**, **EXPLICIT** issue reports. To make the communication more efficient, we wish everyone could search if your issue is an existing one in the searching list. If you find it existing, please add your details in comments under the existing issue instead of opening a brand new one. + +To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](https://github.com/aicworld/.github/tree/main/.github/ISSUE_TEMPLATE) for issue reporters. You can find three kinds of issue templates there: question, bug report and feature request. Please **BE SURE** to follow the instructions to fill fields in template. + +**There are a lot of cases when you could open an issue:** + ++ bug report ++ feature request ++ interview performance issues ++ feature proposal ++ feature design ++ help wanted ++ doc incomplete ++ test improvement ++ any questions on interview project ++ and so on + +Also, we must be reminded when submitting a new question about interview, please remember to remove the sensitive data from your post. Sensitive data could be password, secret key, network locations, private business data and so on. + +> **Note** +> We have requirements for **Commits**, **PR**, **Docs**, and good standards help us collaborate better and understand what you're doing. + +#### Commit Rules + +Actually in interview, we take two rules serious when committing: + +**πŸ₯‡ Commit Message:** + +Commit message could help reviewers better understand what the purpose of submitted PR is. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than ambiguous message. In general, we advocate the following commit message type: + +We use [Semantic Commits](https://www.conventionalcommits.org/en/v1.0.0/) to make it easier to understand what a commit does and to build pretty changelogs. Please use the following prefixes for your commits: + ++ `docs: xxxx`. For example, "docs: add docs about storage installation". ++ `feature: xxxx`.For example, "feature: make result show in sorted order". ++ `bugfix: xxxx`. For example, "bugfix: fix panic when input nil parameter". ++ `style: xxxx`. For example, "style: format the code style of Constants.java". ++ `refactor: xxxx.` For example, "refactor: simplify to make codes more readable". ++ `test: xxx`. For example, "test: add unit test case for func InsertIntoArray". ++ `chore: xxx.` For example, "chore: integrate travis-ci". It's the type of mantainance change. ++ other readable and explicit expression ways. + +On the other side, we discourage contributors from committing message like the following ways: + ++ ~~fix bug~~ ++ ~~update~~ ++ ~~add doc~~ + +**πŸ₯ˆ Commit Content:** + +Commit content represents all content changes included in one commit. We had better include things in one single commit which could support reviewer's complete review without any other commits' help. + +In another word, contents in one single commit can pass the CI to avoid code mess. In brief, there are two minor rules for us to keep in mind: + +1. avoid very large change in a commit. +2. complete and reviewable for each commit. +3. words are written in lowercase English, not uppercase English or other languages such as Chinese. + +No matter what the commit message, or commit content is, we do take more emphasis on code review. + +An example for this could be: + +```bash +❯ git commit -a -s -m "docs: add a new section to the readme" +``` + +#### PR Description + +PR is the only way to make change to interview project files. To help reviewers better get your purpose, **PR** description could not be too detailed. We encourage contributors to follow the [PR template](https://github.com/aicworld/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request. + +You can find some very formal PR in [RFC](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+RFC+label%3ARFC) issues and learn about them. + +**πŸ“– Opening PRs:** + ++ As long as you are working on your **PR**, please mark it as a draft. ++ Please make sure that your **PR** is up-to-date with the latest changes in `main` ++ Mention the issue that your **PR** is addressing. For example, `Fixes: #{ID_1}, #{ID_2}` ++ Make sure that your **PR** passes all checks. + +**🈴 Reviewing PRs:** + ++ Be respectful and constructive. ++ Assign yourself to the **PR**. ++ Check if all checks are passing. ++ Suggest changes instead of simply commenting on found issues. ++ If you are unsure about something, ask the author. ++ If you are not sure if the changes work, try them out. ++ Reach out to other reviewers if you are unsure about something. ++ If you are happy with the changes, approve the **PR**. ++ Merge the **PR** once it has all approvals and the checks are passing. + +**⚠️ DCO check:** + +We have a [DCO check](https://github.com/apps/dco) which runs on every **PR** to verify that the commit has been signed off. + +Once [installed](https://github.com/apps/dco#usage), this integration will set the [status](https://developer.github.com/v3/repos/statuses/) to `failed` if commits in a **Pull Request** do not contain a valid `Signed-off-by` line. + +To sign off the last commit you made, you can use: + +```bash +❯ git commit --amend --signoff +``` + +Contributors *sign-off* that they adhere to these requirements by adding a `Signed-off-by` line to commit messages. + +Git even has a `-s` command line option to append this automatically to your commit message: + +```bash +❯ git commit -s -m "docs: this is my commit message" +``` + +You can also automate signing off your commits by adding the following to your `.zshrc` or `.bashrc`: + +```bash +❯ cat ~/.bashrc || cat ~/.zshrc +git() { + if [ $# -gt 0 ] && [[ "$1" == "commit" ]] ; then + shift + command git commit --signoff "$@" + else + command git "$@" + fi +} +``` + + +#### CI actions + +We host CI on [GitHub Actions](https://github.com/aicworld/interview/actions), we will make sure PR pass tests before we can merge it. + +These two kind of tests: `lint` and `unit test` + +`lint` tests if your code matches our code conventions, please consult [golangci-lint](https://golangci-lint.run/) and [lint config](https://github.com/aicworld/interview/blob/main/.golangci.yml) + +> **Note** +> +> You can use the [Makefile](./Makefile) to run Lint with the command `make lint`. + + +> **Note** +> +> We use the [Makefile](./Makefile) utility, `make tese` to run the unit tests, and the `make cover` utility to check the unit test coverage. + +Try your best to keep every function has been tested, it keeps the function behaves as intended. + +#### Docs Contribution + +**The documentation for interview includes:** + ++ [README.md](https://github.com/aicworld/interview/blob/main/README.md): This file includes the basic information and instructions for getting started with interview. ++ [CONTRIBUTING.md](https://github.com/aicworld/interview/blob/main/CONTRIBUTING.md): This file contains guidelines for contributing to interview's codebase, such as how to submit issues, pull requests, and code reviews. ++ [Official Documentation](https://doc.rentsoft.cn/): This is the official documentation for interview, which includes comprehensive information on all of its features, configuration options, and troubleshooting tips. + +**Please obey the following rules to better format the docs, which would greatly improve the reading experience.** + +1. Please do not use Chinese punctuations in English docs, and vice versa. +2. Please use upper case letters where applicable, like the first letter of sentences / headings, etc. +3. Please specify a language for each Markdown code blocks, unless there's no associated languages. +4. Please insert a whitespace between Chinese and English words. +5. Please use the correct case for technical terms, such as using `HTTP` instead of http, `MySQL` rather than mysql, `Kubernetes` instead of kubernetes, etc. +6. Please check if there's any typos in the docs before submitting PRs. + +**Markfile Lint:** +We integrated in the CICD actions [markdownlint](https://github.com/markdownlint/markdownlint), it detects Markfile specification. + +> **Note** +> We recommend reading [markdownlint rules](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md), This document contains a description of all rules, what they are checking for, as well as an examples of documents that break the rule and corrected versions of the examples. + + + + +## Engage to help anything + +We choose GitHub as the primary place for interview to collaborate. So the latest updates of interview are always here. Although contributions via **PR** is an explicit way to help, we still call for any other ways. + ++ reply to other's [issues](https://github.com/aicworld/interview/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) if you could; ++ help solve other user's problems; ++ help review other's [PR](https://github.com/aicworld/interview/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc) design; ++ discuss about interview to make things clearer; ++ advocate [interview](https://google.com/search?q=interview) technology beyond GitHub; ++ write blogs on interview and so on. + +In a word, **ANY HELP IS CONTRIBUTION.** + + + +## Release version + +Releases of interview are done using [Release Please](https://github.com/googleapis/release-please) and [GoReleaser](https://goreleaser.com/). The workflow looks like this: + +🎯 **A PR is merged to the `main` branch:** + ++ Release please is triggered, creates or updates a new release PR ++ This is done with every merge to main, the current release PR is updated every time + +🎯 **Merging the 'release please' PR to `main`:** + ++ Release please is triggered, creates a new release and updates the changelog based on the commit messages ++ GoReleaser is triggered, builds the binaries and attaches them to the release ++ Containers are created and pushed to the container registry + +With the next relevant merge, a new release PR will be created and the process starts again + +πŸ‘€ **Manually setting the version:** + +If you want to manually set the version, you can create a PR with an empty commit message that contains the version number in the commit message. For example: + +Such a commit can get produced as follows: + +````bash +❯ git commit --allow-empty -m "chore: release 0.0.3" -m "Release-As: 0.0.3 +```` + + +## Contact Us + +We value close connections with our users, developers, and contributors here at interview. With a large community and maintainer team, we're always here to help and support you. Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us. + +Our most recommended way to get in touch is through [Slack](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg). Even if you're in China, Slack is usually not blocked by firewalls, making it an easy way to connect with us. Our Slack community is the ideal place to discuss and share ideas and suggestions with other users and developers of interview. You can ask technical questions, seek help, or share your experiences with other users of interview. + +In addition to Slack, we also offer the following ways to get in touch: + ++ We also have Slack channels for you to communicate and discuss. To join, visit https://slack.com/ and join our [πŸ‘€ interview slack](https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) team channel. ++ Get in touch with us on [Gmail](https://mail.google.com/mail/u/0/?fs=1&tf=cm&to=winxu81@gmail.com). If you have any questions or issues that need resolving, or any suggestions and feedback for our open source projects, please feel free to contact us via email. ++ Read our [blog](https://doc.rentsoft.cn/). Our blog is a great place to stay up-to-date with interview projects and trends. On the blog, we share our latest developments, tech trends, and other interesting information. ++ Add [Wechat](https://github.com/aicworld/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) and indicate that you are a user or developer of interview. We will process your request as soon as possible. + +Whether you're looking to join our community or have any questions or suggestions, we welcome you to get in touch with us. \ No newline at end of file diff --git a/LICENSE copy b/LICENSE copy new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE copy @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..15dc75e --- /dev/null +++ b/Makefile @@ -0,0 +1,564 @@ +# Copyright 2023 aicworld. All rights reserved. +# Use of this source code is governed by a MIT style +# license that can be found in the LICENSE file. + +###################################=> common commands <=############################################# +# ========================== Capture Environment =============================== +# get the repo root and output path +ROOT_PACKAGE=github.com/aicworld/interview +OUT_DIR=$(REPO_ROOT)/_output +# ============================================================================== + +# define the default goal +# + +SHELL := /bin/bash +DIRS=$(shell ls) +GO=go + +.DEFAULT_GOAL := help + +# include the common makefile +COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +# ROOT_DIR: root directory of the code base +ifeq ($(origin ROOT_DIR),undefined) +ROOT_DIR := $(abspath $(shell cd $(COMMON_SELF_DIR)/. && pwd -P)) +endif + +# OUTPUT_DIR: The directory where the build output is stored. +ifeq ($(origin OUTPUT_DIR),undefined) +OUTPUT_DIR := $(ROOT_DIR)/_output +$(shell mkdir -p $(OUTPUT_DIR)) +endif + +# BIN_DIR: The directory where the build output is stored. +ifeq ($(origin BIN_DIR),undefined) +BIN_DIR := $(OUTPUT_DIR)/bin +$(shell mkdir -p $(BIN_DIR)) +endif + +ifeq ($(origin TOOLS_DIR),undefined) +TOOLS_DIR := $(OUTPUT_DIR)/tools +$(shell mkdir -p $(TOOLS_DIR)) +endif + +ifeq ($(origin TMP_DIR),undefined) +TMP_DIR := $(OUTPUT_DIR)/tmp +$(shell mkdir -p $(TMP_DIR)) +endif + +ifeq ($(origin VERSION), undefined) +VERSION := $(shell git describe --tags --always --match="v*" --dirty | sed 's/-/./g') #v2.3.3.631.g00abdc9b.dirty +endif + +# Check if the tree is dirty. default to dirty(maybe u should commit?) +GIT_TREE_STATE:="dirty" +ifeq (, $(shell git status --porcelain 2>/dev/null)) + GIT_TREE_STATE="clean" +endif +GIT_COMMIT:=$(shell git rev-parse HEAD) + +# Image URL to use all building/pushing image targets +IMG ?= openim/interview:test + +BUILDFILE = "./main.go" +BUILDAPP = "$(OUTPUT_DIR)/" + +# Define the directory you want to copyright +CODE_DIRS := $(ROOT_DIR)/.github $(ROOT_DIR)/server $(ROOT_DIR)/scripts $(ROOT_DIR)/build $(ROOT_DIR)/web $(ROOT_DIR)/kf_plugins +FINDS := find $(CODE_DIRS) + +ifndef V +MAKEFLAGS += --no-print-directory +endif + +# The OS must be linux when building docker images +PLATFORMS ?= linux_s390x linux_mips64 linux_mips64le darwin_amd64 windows_amd64 linux_amd64 linux_arm64 linux_ppc64le + +# Set a specific PLATFORM +ifeq ($(origin PLATFORM), undefined) + ifeq ($(origin GOOS), undefined) + GOOS := $(shell go env GOOS) + endif + ifeq ($(origin GOARCH), undefined) + GOARCH := $(shell go env GOARCH) + endif + PLATFORM := $(GOOS)_$(GOARCH) + # Use linux as the default OS when building images + IMAGE_PLAT := linux_$(GOARCH) +else + GOOS := $(word 1, $(subst _, ,$(PLATFORM))) + GOARCH := $(word 2, $(subst _, ,$(PLATFORM))) + IMAGE_PLAT := $(PLATFORM) +endif + +# Copy githook scripts when execute makefile +# TODO! GIT_FILE_SIZE_LIMIT=42000000 git commit -m "This commit is allowed file sizes up to 42MB" +COPY_GITHOOK:=$(shell cp -f scripts/githooks/* .git/hooks/; chmod +x .git/hooks/*) + +# Linux command settings +FIND := find . ! -path './image/*' ! -path './vendor/*' ! -path './bin/*' +XARGS := xargs -r + +# ============================================================================== +# TODO: License selection +# LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/template/license_templates.txt # MIT License +LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/template/LICENSE_TEMPLATES # Apache License + +# COMMA: Concatenate multiple strings to form a list of strings +COMMA := , +# SPACE: Used to separate strings +SPACE := +# SPACE: Replace multiple consecutive Spaces with a single space +SPACE += + +# ============================================================================== +# Build definition + +GO_SUPPORTED_VERSIONS ?= 1.18|1.19|1.20|1.21 +GO_LDFLAGS += -X $(VERSION_PACKAGE).GitVersion=$(VERSION) \ + -X $(VERSION_PACKAGE).GitCommit=$(GIT_COMMIT) \ + -X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \ + -X $(VERSION_PACKAGE).BuildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +ifneq ($(DLV),) + GO_BUILD_FLAGS += -gcflags "all=-N -l" + LDFLAGS = "" +endif +GO_BUILD_FLAGS += -ldflags "$(GO_LDFLAGS)" + +# The use of make for Windows is not recommended +ifeq ($(GOOS),windows) + GO_OUT_EXT := .exe +endif + +ifeq ($(ROOT_PACKAGE),) + $(error the variable ROOT_PACKAGE must be set prior to including golang.mk) +endif + +GOPATH := $(shell go env GOPATH) +ifeq ($(origin GOBIN), undefined) + GOBIN := $(GOPATH)/bin +endif + +ifeq ($(OS),Windows_NT) + NULL := + SPACE := $(NULL) $(NULL) + ROOT_DIR := $(subst $(SPACE),\$(SPACE),$(shell cd)) +else + ROOT_DIR := $(shell pwd) +endif + +COMMANDS := $(filter-out %.md, $(wildcard $(ROOT_DIR)/server/cmd/*)) +BINS := $(notdir $(COMMANDS)) + +ifeq ($(strip $(COMMANDS)),) + $(error Could not determine COMMANDS, set ROOT_DIR or run in source dir) +endif +ifeq ($(strip $(BINS)),) + $(error Could not determine BINS, set ROOT_DIR or run in source dir) +endif + + +EXCLUDE_TESTS=github.com/aicworld/interview/test + +# ============================================================================== +# Build + +## all: Build all the necessary targets. +.PHONY: all +all: copyright-verify tidy lint cover build + +## build: Build binaries by default. +.PHONY: build +build: # go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) + @echo "===========> Building binary $(BUILDAPP) *[Git Info]: $(VERSION)-$(GIT_COMMIT)" + @cd $(SERVER_DIR) && CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/platforms/interview $(ROOT_DIR)/server/main.go + +.PHONY: build.% +build.%: + @echo "$(shell go version)" + @echo "===========> Building binary $(BUILDAPP) *[Git Info]: $(VERSION)-$(GIT_COMMIT)" + @cd $(SERVER_DIR) && export CGO_ENABLED=0 && GOOS=linux go build -o $(BUILDAPP)/$*/ -ldflags '-s -w' $*/example/$(BUILDFILE) + +.PHONY: go.build.verify +go.build.verify: +ifneq ($(shell $(GO) version | grep -q -E '\bgo($(GO_SUPPORTED_VERSIONS))\b' && echo 0 || echo 1), 0) + $(error unsupported go version. Please make install one of the following supported version: '$(GO_SUPPORTED_VERSIONS)') +endif + +## go.build: Build the binary file of the specified platform. +.PHONY: go.build.% +go.build.%: + $(eval COMMAND := $(word 2,$(subst ., ,$*))) + $(eval PLATFORM := $(word 1,$(subst ., ,$*))) + $(eval OS := $(word 1,$(subst _, ,$(PLATFORM)))) + $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) + @cd $(SERVER_DIR) + @echo "=====> COMMAND=$(COMMAND)" + @echo "=====> PLATFORM=$(PLATFORM)" + @echo "=====> BIN_DIR=$(BIN_DIR)" + @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS)_$(ARCH)" + @mkdir -p $(BIN_DIR)/platforms/$(OS)/$(ARCH) + @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) + +## build-multiarch: Build binaries for multiple platforms. +.PHONY: build-multiarch +build-multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) + +.PHONY: test.junit-report +test.junit-report: tools.verify.go-junit-report + @touch $(TMP_DIR)/coverage.out + @cd $(SERVER_DIR) + @echo "===========> Run unit test > $(TMP_DIR)/report.xml" +# @$(GO) test -v -coverprofile=$(TMP_DIR)/coverage.out 2>&1 $(GO_BUILD_FLAGS) ./... | $(TOOLS_DIR)/go-junit-report -set-exit-code > $(TMP_DIR)/report.xml + @$(GO) test -v -coverprofile=$(TMP_DIR)/coverage.out 2>&1 ./... | $(TOOLS_DIR)/go-junit-report -set-exit-code > $(TMP_DIR)/report.xml + @sed -i '/mock_.*.go/d' $(TMP_DIR)/coverage.out + @echo "===========> Test coverage of Go code is reported to $(TMP_DIR)/coverage.html by generating HTML" + @$(GO) tool cover -html=$(TMP_DIR)/coverage.out -o $(TMP_DIR)/coverage.html + +# ============================================================================== +# Targets + +SERVER_DIR := server + +## run: Run the server. +.PHONY: run +run: + @echo "===========> Run the server" + @cd $(SERVER_DIR) && $(GO) run main.go + +## tidy: tidy go.mod +.PHONY: tidy +tidy: + @cd $(SERVER_DIR) && $(GO) mod tidy + +## style: Code style -> fmt,vet,lint +.PHONY: style +style: fmt vet lint + +## fmt: Run go fmt against code. +.PHONY: fmt +fmt: + @cd $(SERVER_DIR) && $(GO) fmt ./... + +## vet: Run go vet against code. +.PHONY: vet +vet: + @cd $(SERVER_DIR) && $(GO) vet ./... + +## generate: Run go generate against code and docs. +.PHONY: generate +generate: + @cd $(SERVER_DIR) && $(GO) generate ./... + +## githook: Copy githook scripts when execute makefile +.PHONY: githook +githook: + @echo "===========> Copy githook scripts when execute makefile" + @./scripts/init-githooks.sh + +## lint: Run go lint against code. +# go1.19+ +.PHONY: lint +lint: tools.verify.golangci-lint + @echo "===========> Run golangci to lint source codes" + @cd $(SERVER_DIR) && $(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/server/... + +## format: Run unit test and format codes +.PHONY: format +format: tools.verify.golines tools.verify.goimports + @echo "===========> Formating codes" + @$(FIND) -type f -name '*.go' | $(XARGS) gofmt -s -w + @$(FIND) -type f -name '*.go' | $(XARGS) $(TOOLS_DIR)/goimports -w -local $(ROOT_PACKAGE) + @$(FIND) -type f -name '*.go' | $(XARGS) $(TOOLS_DIR)/golines -w --max-len=200 --reformat-tags --shorten-comments --ignore-generated . + @cd $(SERVER_DIR) && $(GO) mod edit -fmt + +## updates: Check for updates to go.mod dependencies +.PHONY: updates +updates: tools.verify.go-mod-outdated + @cd $(SERVER_DIR) && $(GO) list -u -m -json all | $(TOOLS_DIR)/go-mod-outdated -update -direct + +## test: Run unit test +.PHONY: test +test: + @cd $(SERVER_DIR) && go test ./... + +## cover: Run unit test with coverage. +.PHONY: cover +cover: test.junit-report + @cd $(SERVER_DIR) && $(GO) tool cover -func=$(TMP_DIR)/coverage.out | \ + awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk + +## docker-build: Build docker image with the manager. +.PHONY: docker-build +docker-build: test + docker build --pull --no-cache . -t ${IMG} + +## docker-push: Push docker image with the manager. +.PHONY: docker-push +docker-push: + docker push ${IMG} + +## docker-buildx-push: Push docker image with the manager using buildx. +.PHONY: docker-buildx-push +docker-buildx-push: + docker buildx build -f --pull --no-cache --platform=$(PLATFORMS) --push . -t $(IMG) + +## copyright-verify: Validate boilerplate headers for assign files. +.PHONY: copyright-verify +copyright-verify: tools.verify.addlicense copyright-add + @echo "===========> Validate boilerplate headers for assign files starting in the $(ROOT_DIR) directory" + @$(TOOLS_DIR)/addlicense -v -check -ignore **/server/test/** -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End of boilerplate headers check..." + +## copyright-add: Add the boilerplate headers for all files. +.PHONY: copyright-add +copyright-add: tools.verify.addlicense + @echo "===========> Adding $(LICENSE_TEMPLATE) the boilerplate headers for all files" + @$(TOOLS_DIR)/addlicense -y $(shell date +"%Y") -v -c "interview & OpenIM open source community." -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End the copyright is added..." + +## swagger: Generate swagger document. +.PHONY: swagger +swagger: tools.verify.swagger + @echo "===========> Generating swagger API docs" + @$(TOOLS_DIR)/swagger generate spec --scan-models -w $(ROOT_DIR)/server/cmd/gendocs -o $(ROOT_DIR)/server/docs/swagger.yaml + +## serve-swagger: Serve swagger spec and docs. +.PHONY: swagger.serve +serve-swagger: tools.verify.swagger + @$(TOOLS_DIR)/swagger serve -F=redoc --no-open --port 36666 $(ROOT_DIR)/server/docs/swagger.yaml + +## release: release the project +.PHONY: release +release: release.verify release.ensure-tag + @scripts/release.sh + +## release.verify: Check if a tool is installed and install it +.PHONY: release.verify +release.verify: tools.verify.git-chglog tools.verify.github-release tools.verify.coscmd tools.verify.coscli + +## release.tag: release the project +.PHONY: release.tag +release.tag: tools.verify.gsemver release.ensure-tag + @git push origin `git describe --tags --abbrev=0` + +## release.ensure-tag: ensure tag +.PHONY: release.ensure-tag +release.ensure-tag: tools.verify.gsemver + @scripts/ensure_tag.sh + +## clean: Clean all builds. +.PHONY: clean +clean: + @echo "===========> Cleaning all builds TMP_DIR($(TMP_DIR)) AND BIN_DIR($(BIN_DIR))" + @-rm -vrf $(TMP_DIR) $(BIN_DIR) + @echo "===========> End clean..." + +## help: Show this help info. +.PHONY: help +help: Makefile + @printf "\n\033[1mUsage: make ...\033[0m\n\n\\033[1mTargets:\\033[0m\n\n" + @sed -n 's/^##//p' $< | awk -F':' '{printf "\033[36m%-28s\033[0m %s\n", $$1, $$2}' | sed -e 's/^/ /' + +######################################=> common tools<= ############################################ +# tools + +BUILD_TOOLS ?= go-gitlint golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo go-junit-report + +## tools.verify.%: Check if a tool is installed and install it +.PHONY: tools.verify.% +tools.verify.%: + @echo "===========> Verifying $* is installed" + @if [ ! -f $(TOOLS_DIR)/$* ]; then GOBIN=$(TOOLS_DIR) $(MAKE) tools.install.$*; fi + @echo "===========> $* is install in $(TOOLS_DIR)/$*" + +# tools: Install a must tools +.PHONY: tools +tools: $(addprefix tools.verify., $(BUILD_TOOLS)) + +# tools.install.%: Install a single tool in $GOBIN/ +.PHONY: tools.install.% +tools.install.%: + @echo "===========> Installing $,The default installation path is $(GOBIN)/$*" + @$(MAKE) install.$* + +.PHONY: install.golangci-lint +install.golangci-lint: + @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +.PHONY: install.goimports +install.goimports: + @$(GO) install golang.org/x/tools/cmd/goimports@latest + +.PHONY: install.addlicense +install.addlicense: + @$(GO) install github.com/google/addlicense@latest + +.PHONY: install.deepcopy-gen +install.deepcopy-gen: + @$(GO) install k8s.io/code-generator/cmd/deepcopy-gen@latest + +.PHONY: install.conversion-gen +install.conversion-gen: + @$(GO) install k8s.io/code-generator/cmd/conversion-gen@latest + +.PHONY: install.ginkgo +install.ginkgo: + @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 + +# git hook +.PHONY: install.go-gitlint +install.go-gitlint: + @$(GO) install github.com/llorllale/go-gitlint@latest + +.PHONY: install.go-junit-report +install.go-junit-report: + @$(GO) install github.com/jstemmer/go-junit-report@latest + +## install.gotests: Install gotests, used to generate go tests +.PHONY: install.swagger +install.swagger: + @$(GO) install github.com/go-swagger/go-swagger/cmd/swagger@latest + +# ============================================================================== +# Tools that might be used include go gvm, cos +# + +## install.kube-score: Install kube-score, used to check kubernetes yaml files +.PHONY: install.kube-score +install.kube-score: + @$(GO) install github.com/zegl/kube-score/cmd/kube-score@latest + +## install.kubeconform: Install kubeconform, used to check kubernetes yaml files +.PHONY: install.kubeconform +install.kubeconform: + @$(GO) install github.com/yannh/kubeconform/cmd/kubeconform@latest + +## install.gsemver: Install gsemver, used to generate semver +.PHONY: install.gsemver +install.gsemver: + @$(GO) install github.com/arnaud-deprez/gsemver@latest + +## install.hugo: Install hugo, used to generate website +.PHONY: install.hugo +install.hugo: + @$(GO) install github.com/gohugoio/hugo@latest + +## install.git-chglog: Install git-chglog, used to generate changelog +.PHONY: install.git-chglog +install.git-chglog: + @$(GO) install github.com/git-chglog/git-chglog/cmd/git-chglog@latest + +## install.github-release: Install github-release, used to create github release +.PHONY: install.github-release +install.github-release: + @$(GO) install github.com/github-release/github-release@latest + +## install.goreleaser: Install goreleaser, used to release go program +.PHONY: install.goreleaser +install.goreleaser: + @$(GO) install github.com/goreleaser/goreleaser@latest + +## install.coscli: Install coscli, used to upload files to cos +# example: ./coscli cp/sync -r /root/workspaces/aicworld/interview/ cos://aicworld-1306374445/code/ -e cos.ap-hongkong.myqcloud.com +# https://cloud.tencent.com/document/product/436/71763 +# aicworld/* +# - code/ +# - docs/ +# - images/ +# - scripts/ +.PHONY: install.coscli +install.coscli: + @wget -q https://github.com/tencentyun/coscli/releases/download/v0.13.0-beta/coscli-linux -O ${TOOLS_DIR}/coscli + @chmod +x ${TOOLS_DIR}/coscli + +## install.coscmd: Install coscmd, used to upload files to cos +.PHONY: install.coscmd +install.coscmd: + @if which pip &>/dev/null; then pip install coscmd; else pip3 install coscmd; fi + +## install.delve: Install delve, used to debug go program +.PHONY: install.delve +install.delve: + @$(GO) install github.com/go-delve/delve/cmd/dlv@latest + +## install.swag: Install swag, used to generate swagger +# go1.17+ +# go-swagger is more powerful than swag +# http://localhost:8080/swagger/index.html +.PHONY: install.swag +install.swag: + @$(GO) install github.com/swaggo/swag/cmd/swag@latest + +## install.go-swagger: Install go-swagger, used to generate swagger +.PHONY: install.go-swagger +install.go-swagger: + @$(GO) install github.com/go-swagger/go-swagger/cmd/swagger@latest + +## install.air: Install air, used to hot reload go program +.PHONY: install.air +install.air: + @$(GO) install github.com/cosmtrek/air@latest + +## install.gvm: Install gvm, gvm is a Go version manager, built on top of the official go tool. +.PHONY: install.gvm +install.gvm: + @echo "===========> Installing gvm,The default installation path is ~/.gvm/script/gvm" + @bash < <(curl -s -S -L https://raw.gitee.com/moovweb/gvm/master/binscripts/gvm-installer) + @$(shell source /root/.gvm/script/gvm) + +## install.golines: Install golines, used to format long lines +.PHONY: install.golines +install.golines: + @$(GO) install github.com/segmentio/golines@latest + +## install.go-mod-outdated: Install go-mod-outdated, used to check outdated dependencies +.PHONY: install.go-mod-outdated +install.go-mod-outdated: + @$(GO) install github.com/psampaz/go-mod-outdated@latest + +## install.mockgen: Install mockgen, used to generate mock functions +.PHONY: install.mockgen +install.mockgen: + @$(GO) install github.com/golang/mock/mockgen@latest + +## install.gotests: Install gotests, used to generate test functions +.PHONY: install.gotests +install.gotests: + @$(GO) install github.com/cweill/gotests/gotests@latest + +## install.protoc-gen-go: Install protoc-gen-go, used to generate go source files from protobuf files +.PHONY: install.protoc-gen-go +install.protoc-gen-go: + @$(GO) install github.com/golang/protobuf/protoc-gen-go@latest + +## install.cfssl: Install cfssl, used to generate certificates +.PHONY: install.cfssl +install.cfssl: + @$(ROOT_DIR)/script/install/install.sh iam::install::install_cfssl + +## install.depth: Install depth, used to check dependency tree +.PHONY: install.depth +install.depth: + @$(GO) install github.com/KyleBanks/depth/cmd/depth@latest + +## install.go-callvis: Install go-callvis, used to visualize call graph +.PHONY: install.go-callvis +install.go-callvis: + @$(GO) install github.com/ofabry/go-callvis@latest + +## install.gothanks: Install gothanks, used to thank go dependencies +.PHONY: install.gothanks +install.gothanks: + @$(GO) install github.com/psampaz/gothanks@latest + +## install.richgo: Install richgo +.PHONY: install.richgo +install.richgo: + @$(GO) install github.com/kyoh86/richgo@latest + +## install.rts: Install rts +.PHONY: install.rts +install.rts: + @$(GO) install github.com/galeone/rts/cmd/rts@latest diff --git a/README.md b/README.md index 2634121..1d88059 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ +

+ + + +

+

+ ⭐️ interview ζ˜―δΈ€δΈͺεœ¨ηΊΏζ™Ίθƒ½ι’θ―•εΉ³ε° ⭐️
+

+ +

+A+ +good first + + + + +

+ +

+ +

+ θ‹±ζ–‡ β€’ + δΈ­ζ–‡ +

+ +

+
+ + # **AIC Interview: An AI-powered Interview Simulation Platform** AIC Interview is an innovative platform leveraging advanced AI technologies to transform the traditional interview process. Built by the team at AICWorld, this platform utilizes large language models to simulate real interview scenarios, providing users with a unique opportunity to practice and enhance their interviewing skills. It offers automated skill assessments, real-time feedback, and personalized improvement suggestions, aiming to prepare candidates for success in their career pursuits. diff --git a/README_zh-CN.md b/README_zh-CN.md new file mode 100644 index 0000000..e7f1717 --- /dev/null +++ b/README_zh-CN.md @@ -0,0 +1,27 @@ +

+ + + +

+

+ ⭐️ interview ζ˜―δΈ€δΈͺεœ¨ηΊΏζ™Ίθƒ½ι’θ―•εΉ³ε° ⭐️
+

+ +

+A+ +good first + + + + +

+ +

+ +

+ θ‹±ζ–‡ β€’ + δΈ­ζ–‡ +

+ +

+
diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..5ef6fce --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,23 @@ +# 2023 Basic Roadmap + +This roadmap is made for interview basic feature. For more information, you can see this [RFC](https://github.com/aicworld/interview/issues/4). + +### Release Base Docker Images. + +- Use `docker-compose` to build and run interview server and web. +- Use `docker-compose` to build and run OpenIM. +- Use `docker-compose` to build and run LLM. + +### Support Basic Custom Service Feature. + +- Support user management. +- Support community management. +- Support web and slack channel. +- Support dashboard for users. +- Support local knowledge base. + +### Optimized the interview architechure. + +- Support scripts to deploy interview. +- Support system trace for interview monitoring and alerting. +- Support `milvus` as vector db with cloud documents extensible feature. diff --git a/assets/README.md b/assets/README.md new file mode 100644 index 0000000..98a6ca7 --- /dev/null +++ b/assets/README.md @@ -0,0 +1,37 @@ +# `/assets` + +The `/assets` directory in the interview repository contains various assets such as images, logos, and animated GIFs. These assets serve different purposes and contribute to the functionality and aesthetics of the interview project. + +## Directory Structure: + +```bash +assets/ +β”œβ”€β”€ README.md # Documentation for the assets directory +β”œβ”€β”€ images # Directory holding images related to interview +β”‚ β”œβ”€β”€ architecture.png # Image depicting the architecture of interview +β”‚ └── mvc.png # Image illustrating the Model-View-Controller (MVC) pattern +β”œβ”€β”€ intive-slack.png # Image displaying the Intive Slack logo +β”œβ”€β”€ logo # Directory containing various logo variations for interview +β”‚ β”œβ”€β”€ interview-logo-black.png # interview logo with a black background +β”‚ β”œβ”€β”€ interview-logo-blue.png # interview logo with a blue background +β”‚ β”œβ”€β”€ interview-logo-green.png # interview logo with a green background +β”‚ β”œβ”€β”€ interview-logo-purple.png # interview logo with a purple background +β”‚ β”œβ”€β”€ interview-logo-white.png # interview logo with a white background +β”‚ β”œβ”€β”€ interview-logo-yellow.png # interview logo with a yellow background +β”‚ β”œβ”€β”€ interview-logo-yellow2.png # Another variation of interview logo with a yellow background +β”‚ └── interview-logo.png # interview logo with a transparent background +└── logo-gif # Directory containing animated GIF versions of the interview logo + β”œβ”€β”€ interview-log-dark.gif # Dark-themed animated interview logo + β”œβ”€β”€ interview-log-dazzling.gif # Dazzling-themed animated interview logo + β”œβ”€β”€ interview-log-insipid.gif # Insipid-themed animated interview logo + β”œβ”€β”€ interview-log-white.gif # White-colored animated interview logo + └── interview-log.gif # Animated interview logo with a transparent background +``` + +## Copyright Notice: + +The interview logo, including its variations and animated versions, displayed in this repository [interview](https://github.com/aicworld/interview) under the `/assets/logo` and `/assets/logo-gif` directories, are protected by copyright laws. + +The logo design is credited to @Xx(席欣). + +Please respect the intellectual property rights and refrain from unauthorized use and distribution of these assets. \ No newline at end of file diff --git a/assets/images/architecture.png b/assets/images/architecture.png new file mode 100644 index 0000000..22f8fd5 Binary files /dev/null and b/assets/images/architecture.png differ diff --git a/assets/images/config_page.png b/assets/images/config_page.png new file mode 100644 index 0000000..98bc0ce Binary files /dev/null and b/assets/images/config_page.png differ diff --git a/assets/images/dashboard_page.png b/assets/images/dashboard_page.png new file mode 100644 index 0000000..a2ea748 Binary files /dev/null and b/assets/images/dashboard_page.png differ diff --git a/assets/images/login_page.png b/assets/images/login_page.png new file mode 100644 index 0000000..772b0d4 Binary files /dev/null and b/assets/images/login_page.png differ diff --git a/assets/images/mvc.png b/assets/images/mvc.png new file mode 100644 index 0000000..a7e0e1e Binary files /dev/null and b/assets/images/mvc.png differ diff --git a/assets/images/platform_page.png b/assets/images/platform_page.png new file mode 100644 index 0000000..a718511 Binary files /dev/null and b/assets/images/platform_page.png differ diff --git a/assets/images/session_page.png b/assets/images/session_page.png new file mode 100644 index 0000000..8275860 Binary files /dev/null and b/assets/images/session_page.png differ diff --git a/assets/intive-slack.png b/assets/intive-slack.png new file mode 100644 index 0000000..3f27e0c Binary files /dev/null and b/assets/intive-slack.png differ diff --git a/assets/logo-gif/LICENSE b/assets/logo-gif/LICENSE new file mode 100644 index 0000000..54d376d --- /dev/null +++ b/assets/logo-gif/LICENSE @@ -0,0 +1 @@ +# The interview logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 International). \ No newline at end of file diff --git a/assets/logo-gif/openkf-logo-black.gif b/assets/logo-gif/openkf-logo-black.gif new file mode 100644 index 0000000..40e552a Binary files /dev/null and b/assets/logo-gif/openkf-logo-black.gif differ diff --git a/assets/logo-gif/openkf-logo-dark.gif b/assets/logo-gif/openkf-logo-dark.gif new file mode 100644 index 0000000..6a73300 Binary files /dev/null and b/assets/logo-gif/openkf-logo-dark.gif differ diff --git a/assets/logo-gif/openkf-logo-dazzling.gif b/assets/logo-gif/openkf-logo-dazzling.gif new file mode 100644 index 0000000..f2fb29d Binary files /dev/null and b/assets/logo-gif/openkf-logo-dazzling.gif differ diff --git a/assets/logo-gif/openkf-logo-insipid.gif b/assets/logo-gif/openkf-logo-insipid.gif new file mode 100644 index 0000000..4b9e9a9 Binary files /dev/null and b/assets/logo-gif/openkf-logo-insipid.gif differ diff --git a/assets/logo-gif/openkf-logo-white.gif b/assets/logo-gif/openkf-logo-white.gif new file mode 100644 index 0000000..b91d371 Binary files /dev/null and b/assets/logo-gif/openkf-logo-white.gif differ diff --git a/assets/logo-gif/openkf-logo.gif b/assets/logo-gif/openkf-logo.gif new file mode 100644 index 0000000..d35e9ee Binary files /dev/null and b/assets/logo-gif/openkf-logo.gif differ diff --git a/assets/logo/LICENSE b/assets/logo/LICENSE new file mode 100644 index 0000000..54d376d --- /dev/null +++ b/assets/logo/LICENSE @@ -0,0 +1 @@ +# The interview logo files are licensed under a choice of either Apache-2.0 or CC-BY-4.0 (Creative Commons Attribution 4.0 International). \ No newline at end of file diff --git a/assets/logo/favicon.ico b/assets/logo/favicon.ico new file mode 100644 index 0000000..eb617ae Binary files /dev/null and b/assets/logo/favicon.ico differ diff --git a/assets/logo/openkf-logo-black.png b/assets/logo/openkf-logo-black.png new file mode 100644 index 0000000..5ceb800 Binary files /dev/null and b/assets/logo/openkf-logo-black.png differ diff --git a/assets/logo/openkf-logo-blue.png b/assets/logo/openkf-logo-blue.png new file mode 100644 index 0000000..85f0194 Binary files /dev/null and b/assets/logo/openkf-logo-blue.png differ diff --git a/assets/logo/openkf-logo-green.png b/assets/logo/openkf-logo-green.png new file mode 100644 index 0000000..a120a7a Binary files /dev/null and b/assets/logo/openkf-logo-green.png differ diff --git a/assets/logo/openkf-logo-purple.png b/assets/logo/openkf-logo-purple.png new file mode 100644 index 0000000..52771b4 Binary files /dev/null and b/assets/logo/openkf-logo-purple.png differ diff --git a/assets/logo/openkf-logo-white.png b/assets/logo/openkf-logo-white.png new file mode 100644 index 0000000..7bde3ea Binary files /dev/null and b/assets/logo/openkf-logo-white.png differ diff --git a/assets/logo/openkf-logo-yellow.png b/assets/logo/openkf-logo-yellow.png new file mode 100644 index 0000000..a39e5a8 Binary files /dev/null and b/assets/logo/openkf-logo-yellow.png differ diff --git a/assets/logo/openkf-logo-yellow2.png b/assets/logo/openkf-logo-yellow2.png new file mode 100644 index 0000000..4c0ec65 Binary files /dev/null and b/assets/logo/openkf-logo-yellow2.png differ diff --git a/assets/logo/openkf-logo.png b/assets/logo/openkf-logo.png new file mode 100644 index 0000000..68de256 Binary files /dev/null and b/assets/logo/openkf-logo.png differ diff --git a/bot/.gitignore b/bot/.gitignore new file mode 100644 index 0000000..5290dfb --- /dev/null +++ b/bot/.gitignore @@ -0,0 +1,5 @@ +__pycache__ +logs +data + +config.yaml \ No newline at end of file diff --git a/bot/README.md b/bot/README.md new file mode 100644 index 0000000..b4f3606 --- /dev/null +++ b/bot/README.md @@ -0,0 +1,22 @@ +# interview Plugins + +Use LangChain and LLM to build local knowledge model. + +## Usage + +**init** + +```bash +cp config.example.yaml config.yaml +``` + +**start:** + +```bash +cd llm && python fastchat_api_runner.py +cd .. && python main.py +``` + +## Reference + +1. [LangChain](https://github.com/langchain-ai/langchain) \ No newline at end of file diff --git a/bot/__init__.py b/bot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/apis/__init__.py b/bot/apis/__init__.py new file mode 100644 index 0000000..6c2dc96 --- /dev/null +++ b/bot/apis/__init__.py @@ -0,0 +1 @@ +import asyncio \ No newline at end of file diff --git a/bot/chains/__init__.py b/bot/chains/__init__.py new file mode 100644 index 0000000..77163d1 --- /dev/null +++ b/bot/chains/__init__.py @@ -0,0 +1,14 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + diff --git a/bot/config.example.yaml b/bot/config.example.yaml new file mode 100644 index 0000000..e69de29 diff --git a/bot/constants/__init__.py b/bot/constants/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/db/__init__.py b/bot/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/llm/__init__.py b/bot/llm/__init__.py new file mode 100644 index 0000000..77163d1 --- /dev/null +++ b/bot/llm/__init__.py @@ -0,0 +1,14 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + diff --git a/bot/main.py b/bot/main.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/models/.gitkeep b/bot/models/.gitkeep new file mode 100644 index 0000000..f55d3dd --- /dev/null +++ b/bot/models/.gitkeep @@ -0,0 +1 @@ +Put LLM checkpoints here. \ No newline at end of file diff --git a/bot/requirements.txt b/bot/requirements.txt new file mode 100755 index 0000000..e69de29 diff --git a/bot/router/__init__.py b/bot/router/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bot/start.sh b/bot/start.sh new file mode 100644 index 0000000..394a34b --- /dev/null +++ b/bot/start.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd llm && python fastchat_api_runner.py +cd .. && python main.py \ No newline at end of file diff --git a/bot/test/README.md b/bot/test/README.md new file mode 100644 index 0000000..86fdcd5 --- /dev/null +++ b/bot/test/README.md @@ -0,0 +1,68 @@ +# Test scripts + +## Test Milvus standalone startup + +### 1. Start Milvus standalone + +```bash +# DIR: /interview/deploy/docker-compose +docker-compose up -d +``` + +### 2. Check with scripts + +```bash +# DIR: /interview/bot/test +# pymilvus==2.1.3 + +python3 test_milvus.py +``` + +### 3. Outputs + +```bash + +=== start connecting to Milvus === + +Does collection hello_milvus exist in Milvus: False + +=== Create collection `hello_milvus` === + + +=== Start inserting entities === + +Number of entities in Milvus: 3000 + +=== Start Creating index IVF_FLAT === + + +=== Start loading === + + +=== Start searching based on vector similarity === +.... +``` + +## Test langchain with llms + +### 1. Start LLM server + +```bash +# DIR: /interview/bot/llm + +python3 fastchat_api_runner.py +``` + +### 2. Setup environment + +```bash +export OPENAI_API_BASE=http://localhost:8888/v1 +export OPENAI_API_KEY=EMPTY +``` + +### 3. Test chats + +```bash +# DIR: /interview/bot/test +python3 test_langchain.py +``` \ No newline at end of file diff --git a/bot/utils/__init__.py b/bot/utils/__init__.py new file mode 100644 index 0000000..32ae6f1 --- /dev/null +++ b/bot/utils/__init__.py @@ -0,0 +1,19 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__all__ = [ + "banner", + "config", + "log" +] \ No newline at end of file diff --git a/bot/utils/banner.py b/bot/utils/banner.py new file mode 100644 index 0000000..2e743fa --- /dev/null +++ b/bot/utils/banner.py @@ -0,0 +1,45 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +sys.path.append(os.path.dirname(os.path.dirname(__file__))) + + +def kf_banner(version: str, debug: bool, log_path: str) -> None: + print(f''' +-------------------------------------------------------------------------------------------------------------------- +_______ ______ ___________ ________ _____ +__ __ \______________________ //_/__ ____/ ___ __ )_______ /_ +_ / / /__ __ \ _ \_ __ \_ ,< __ /_ __ __ | __ \ __/ +/ /_/ /__ /_/ / __/ / / / /| | _ __/ _ /_/ // /_/ / /_ +\____/ _ .___/\___//_/ /_//_/ |_| /_/ /_____/ \____/\__/ + /_/ + +APP Mode: +- Version: %s +- Debug: %s +- Log path: %s + +Github repo: https://github.com/aicworld/interview. +Official website: https://www.openim.online/en +interview Slack: https://join.slack.com/t/aicworld/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg (interview clannels) +πŸŽ‰πŸŽ‰ Welcome to your contribution :) + +Copyright Β© 2023 OpenIM open source community. All rights reserved. +Licensed under the Apache License (the "License"); +-------------------------------------------------------------------------------------------------------------------- +''' % (version, debug, log_path)) + \ No newline at end of file diff --git a/bot/utils/config.py b/bot/utils/config.py new file mode 100644 index 0000000..1c006d4 --- /dev/null +++ b/bot/utils/config.py @@ -0,0 +1,137 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +import yaml +from colorama import Fore + +sys.path.append(os.path.dirname(os.path.dirname(__file__))) + +class KBConfig: + ''' + KBConfig is a class that loads the configuration file. + Use load_config to load the configuration file, and use get_* to get the configuration. + ''' + def __init__(self, file: str) -> None: + self._config = None + + with open(file, encoding="utf-8") as fp: + self._config = yaml.safe_load(fp.read()) + + ############################### + # interview bot config + ############################### + def get_app_version(self) -> str: + return self._config['app']['version'] + + def get_app_host(self) -> str: + return self._config['app']['host'] if self._config['app']['host'] else "0.0.0.0" + + def get_app_port(self) -> str: + return self._config['app']['port'] + + def get_app_debug(self) -> str: + return self._config['app']['debug'] + + def get_app_file_dir(self) -> str: + return self._config['app']['file_dir'] + + def get_app_log_path(self) -> str: + return self._config['app']['log_path'] + + def get_app_doc(self) -> str: + return self._config['app']['doc'] + + def get_app_token(self) -> str: + return self._config['app']['token'] + + def get_openai_api_key(self) -> str: + return self._config['app']['openai_api_key'] + + ############################### + # LLM langchain config + ############################### + def get_inference_device(self) -> str: + return self._config['inference']['device'] + + def get_model_history(self) -> str: + return self._config['model']['history'] + + def get_model_temperature(self) -> str: + return self._config['model']['temperature'] + + def get_model_top_k(self) -> str: + return self._config['model']['top_k'] + + def get_model_top_p(self) -> str: + return self._config['model']['top_p'] + + ############################### + # LLM fastchat config + ############################### + def get_fastchat_models_model_path(self) -> str: + return str(self._config['fastchat']['models']['model_path']) + + def get_fastchat_models_llm_model_name(self) -> str: + return str(self._config['fastchat']['models']['llm_model_name']) + + def get_fastchat_models_embedding_model_name(self) -> str: + return str(self._config['fastchat']['models']['embedding_model_name']) + + def get_fastchat_controller_host(self) -> str: + return str(self._config['fastchat']['controller']['host']) + + def get_fastchat_controller_port(self) -> str: + return str(self._config['fastchat']['controller']['port']) + + def get_fastchat_model_worker_host(self) -> str: + return str(self._config['fastchat']['model_worker']['host']) + + def get_fastchat_model_worker_port(self) -> str: + return str(self._config['fastchat']['model_worker']['port']) + + def get_fastchat_model_worker_device(self) -> str: + return str(self._config['fastchat']['model_worker']['device']) + + def get_fastchat_model_worker_limit_worker_concurrency(self) -> str: + return str(self._config['fastchat']['model_worker']['limit_worker_concurrency']) + + def get_fastchat_model_worker_num_gpus(self) -> str: + return str(self._config['fastchat']['model_worker']['num_gpus']) + + def get_fastchat_model_worker_max_gpu_memory(self) -> str: + return str(self._config['fastchat']['model_worker']['max_gpu_memory']) + + def get_fastchat_openai_api_server_host(self) -> str: + return str(self._config['fastchat']['openai_api_server']['host']) + + def get_fastchat_openai_api_server_port(self) -> str: + return str(self._config['fastchat']['openai_api_server']['port']) + + ############################### + # Milvus config + ############################### + def get_milvus_host(self) -> str: + return self._config['milvus']['host'] + + def get_milvus_port(self) -> str: + return self._config['milvus']['port'] + + def get_milvus_top_k(self) -> str: + return self._config['milvus']['top_k'] + + def get_milvus_score_threshold(self) -> str: + return self._config['milvus']['score_threshold'] \ No newline at end of file diff --git a/build/README.md b/build/README.md new file mode 100644 index 0000000..00bfce3 --- /dev/null +++ b/build/README.md @@ -0,0 +1,11 @@ +# `/build` + +Packaging and Continuous Integration. + +Put your cloud (AMI), container (Docker), OS (deb, rpm, pkg) package configurations and scripts in the `/build/package` directory. + +Put your CI (travis, circle, drone) configurations and scripts in the `/build/ci` directory. Note that some of the CI tools (e.g., Travis CI) are very picky about the location of their config files. Try putting the config files in the `/build/ci` directory linking them to the location where the CI tools expect them when possible (don't worry if it's not and if keeping those files in the root directory makes your life easier :-)). + +Examples: + +* https://github.com/cockroachdb/cockroach/tree/master/build \ No newline at end of file diff --git a/build/goreleaser.yaml b/build/goreleaser.yaml new file mode 100644 index 0000000..e91a369 --- /dev/null +++ b/build/goreleaser.yaml @@ -0,0 +1,405 @@ +# .goreleaser.yaml +before: + hooks: + # You may remove this if you don't use go modules. + - make tidy + - make copyright.add + +snapshot: + name_template: "{{ incpatch .Version }}-next" + +report_sizes: true + +builds: + # You can have multiple builds defined as a yaml list + - # + # ID of the build. + # + # Default: Binary name + id: "interview-server" + + # Path to main.go file or main package. + # Notice: when used with `gomod.proxy`, this must be a package. + # + # Default is `.`. + main: ./server + + # Binary name. + # Can be a path (e.g. `bin/app`) to wrap the binary in a directory. + # + # Default: Project directory name + binary: program + + # Custom flags. + # + # Templates: allowed + flags: + - -tags=dev + - -v + + # Custom asmflags. + # + # Templates: allowed + asmflags: + - -D mysymbol + - all=-trimpath={{.Env.GOPATH}} + + # Custom gcflags. + # + # Templates: allowed + gcflags: + - all=-trimpath={{.Env.GOPATH}} + - ./dontoptimizeme=-N + + # Custom ldflags. + # + # Default: '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser' + # Templates: allowed + ldflags: + - -s -w -X main.build={{.Version}} + - ./usemsan=-msan + + # Custom Go build mode. + # + # Valid options: + # - `c-shared` + # - `c-archive` + # + # Since: v1.13 + buildmode: c-shared + + # Custom build tags templates. + tags: + - osusergo + - netgo + - static_build + - feature + + # Custom environment variables to be set during the builds. + # Invalid environment variables will be ignored. + # + # Default: os.Environ() ++ env config section + # Templates: allowed (since v1.14) + env: + - CGO_ENABLED=0 + # complex, templated envs (v1.14+): + - >- + {{- if eq .Os "darwin" }} + {{- if eq .Arch "amd64"}}CC=o64-clang{{- end }} + {{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }} + {{- end }} + {{- if eq .Os "windows" }} + {{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }} + {{- end }} + + # GOOS list to build for. + # For more info refer to: https://golang.org/doc/install/source#environment + # + # Default: [ 'darwin', 'linux', 'windows' ] + goos: + - freebsd + - windows + + # GOARCH to build for. + # For more info refer to: https://golang.org/doc/install/source#environment + # + # Default: [ '386', 'amd64', 'arm64' ] + goarch: + - amd64 + - arm + - arm64 + + # GOARM to build for when GOARCH is arm. + # For more info refer to: https://golang.org/doc/install/source#environment + # + # Default: [ 6 ] + goarm: + - 6 + - 7 + + # GOAMD64 to build when GOARCH is amd64. + # For more info refer to: https://golang.org/doc/install/source#environment + # + # Default: [ 'v1' ] + goamd64: + - v2 + - v3 + + # GOMIPS and GOMIPS64 to build when GOARCH is mips, mips64, mipsle or mips64le. + # For more info refer to: https://golang.org/doc/install/source#environment + # + # Default: [ 'hardfloat' ] + gomips: + - hardfloat + - softfloat + + # List of combinations of GOOS + GOARCH + GOARM to ignore. + ignore: + - goos: darwin + goarch: 386 + - goos: linux + goarch: arm + goarm: 7 + - goarm: mips64 + - gomips: hardfloat + - goamd64: v4 + + # Optionally override the matrix generation and specify only the final list + # of targets. + # + # Format is `{goos}_{goarch}` with their respective suffixes when + # applicable: `_{goarm}`, `_{goamd64}`, `_{gomips}`. + # + # Special values: + # - go_118_first_class: evaluates to the first-class ports of go1.18. + # - go_first_class: evaluates to latest stable go first-class ports, + # currently same as 1.18. + # + # This overrides `goos`, `goarch`, `goarm`, `gomips`, `goamd64` and + # `ignores`. + targets: + # Since: v1.9 + - go_first_class + # Since: v1.9 + - go_118_first_class + - linux_amd64_v1 + - darwin_arm64 + - linux_arm_6 + + # Set a specific go binary to use when building. + # It is safe to ignore this option in most cases. + # + # Default is "go" + gobinary: "go1.13.4" + + # Sets the command to run to build. + # Can be useful if you want to build tests, for example, + # in which case you can set this to "test". + # It is safe to ignore this option in most cases. + # + # Default: build. + # Since: v1.9 + command: test + + # Set the modified timestamp on the output binary, typically + # you would do this to ensure a build was reproducible. Pass + # empty string to skip modifying the output. + mod_timestamp: "{{ .CommitTimestamp }}" + + # Hooks can be used to customize the final binary, + # for example, to run generators. + # + # Templates: allowed + hooks: + pre: rice embed-go + post: ./script.sh {{ .Path }} + + # If true, skip the build. + # Useful for library projects. + skip: false + + # By default, GoReleaser will create your binaries inside + # `dist/${BuildID}_${BuildTarget}`, which is a unique directory per build + # target in the matrix. + # You can set subdirs within that folder using the `binary` property. + # + # However, if for some reason you don't want that unique directory to be + # created, you can set this property. + # If you do, you are responsible for keeping different builds from + # overriding each other. + no_unique_dist_dir: true + + # By default, GoReleaser will check if the main filepath has a main + # function. + # This can be used to skip that check, in case you're building tests, for + # example. + # + # Since: v1.9 + no_main_check: true + + # Path to project's (sub)directory containing Go code. + # This is the working directory for the Go build command(s). + # If dir does not contain a `go.mod` file, and you are using `gomod.proxy`, + # produced binaries will be invalid. + # You would likely want to use `main` instead of this. + # + # Default: '.' + dir: go + + # Builder allows you to use a different build implementation. + # This is a GoReleaser Pro feature. + # Valid options are: `go` and `prebuilt`. + # + # Default: 'go' + builder: prebuilt + + # Overrides allows to override some fields for specific targets. + # This can be specially useful when using CGO. + # Note: it'll only match if the full target matches. + # + # Since: v1.5 + overrides: + - goos: darwin + goarch: arm64 + goamd64: v1 + goarm: "" + gomips: "" + ldflags: + - foo + tags: + - bar + asmflags: + - foobar + gcflags: + - foobaz + env: + - CGO_ENABLED=1 + +# TODO:Need a script, such as the init - release to help binary to find the right directory +# ,which can be compiled binary +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of uname. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + + # Set this to true if you want all files in the archive to be in a single directory. + # If set to true and you extract the archive 'goreleaser_Linux_arm64.tar.gz', + # you'll get a folder 'goreleaser_Linux_arm64'. + # If set to false, all files are extracted separately. + # You can also set it to a custom folder name (templating is supported). + wrap_in_directory: true + + # use zip for windows archives + files: + - CHANGELOG/* + - deployment/* + - server/config.yaml + - build/* + - scripts/* + - Makefile + - docs/* + - src: "*.md" + dst: docs + + # Strip parent folders when adding files to the archive. + strip_parent: true + + # File info. + # Not all fields are supported by all formats available formats. + # + # Default: copied from the source file + info: + # Templates: allowed (since v1.14) + owner: root + + # Templates: allowed (since v1.14) + group: root + + # Must be in time.RFC3339Nano format. + # + # Templates: allowed (since v1.14) + mtime: "{{ .CommitDate }}" + + # File mode. + mode: 0644 + + format_overrides: + - goos: windows + format: zip + +changelog: + sort: asc + use: github + filters: + exclude: + - "^test:" + - "^chore" + - "merge conflict" + - Merge pull request + - Merge remote-tracking branch + - Merge branch + - go mod tidy + groups: + - title: Dependency updates + regexp: '^.*?(feat|fix)\(deps\)!?:.+$' + order: 300 + - title: "New Features" + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 100 + - title: "Security updates" + regexp: '^.*?sec(\([[:word:]]+\))??!?:.+$' + order: 150 + - title: "Bug fixes" + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 200 + - title: "Documentation updates" + regexp: ^.*?doc(\([[:word:]]+\))??!?:.+$ + order: 400 + - title: "Build process updates" + regexp: ^.*?build(\([[:word:]]+\))??!?:.+$ + order: 400 + - title: Other work + order: 9999 + + +nfpms: + - id: packages + builds: + - interview-server + # Your app's vendor. + vendor: aicworld + homepage: https://github.com/aicworld/Open-IM-Server + maintainer: kubbot + description: |- + Auto sync github labels + kubbot && openimbot + license: MIT + formats: + - apk + - deb + - rpm + - termux.deb # Since: v1.11 + - archlinux # Since: v1.13 + dependencies: + - git + recommends: + - golang + +# Default: './dist' +dist: ./_output/dist + + +# .goreleaser.yaml +milestones: + # You can have multiple milestone configs + - + # Repository for the milestone + # Default is extracted from the origin remote URL + repo: + owner: aicworld + name: interview + + # Whether to close the milestone + close: true + + # Fail release on errors, such as missing milestone. + fail_on_error: false + + # Name of the milestone + # + # Default: '{{ .Tag }}' + name_template: "Current Release" + + +checksum: + name_template: "{{ .ProjectName }}_checksums.txt" + algorithm: sha256 + +release: + prerelease: auto \ No newline at end of file diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS new file mode 100644 index 0000000..d9b7e4b --- /dev/null +++ b/docs/CODEOWNERS @@ -0,0 +1 @@ +* @cubxxw diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..5933803 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,9 @@ +# `/docs` + +Design and user documents (in addition to your godoc generated documentation). + +Examples: + +* https://github.com/gohugoio/hugo/tree/master/docs +* https://github.com/openshift/origin/tree/master/docs +* https://github.com/dapr/dapr/tree/master/docs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..733df16 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "interview", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/scripts/OWNERS b/scripts/OWNERS new file mode 100644 index 0000000..c1327a0 --- /dev/null +++ b/scripts/OWNERS @@ -0,0 +1,6 @@ +reviewers: + - cubxxw + - kubbot +approvers: + - cubxxw + - kubbot \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..04bda00 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,30 @@ +# `/scripts` + +## Supported platforms + +- Linux x86_64 (linux_amd64) : 64-bit Linux for most desktop and server systems. + +- Windows x86_64 (windows_amd64) : 64-bit version for most Windows operating systems. + +- macOS x86_64 (darwin_amd64) : 64-bit version for Apple Macintosh computers. + +- Linux ARM64 (linux_arm64) : For ARM-based 64-bit Linux systems such as Raspberry Pi 4 and Jetson Nano. + +- Linux s390x (linux_s390x) : 64-bit Linux for IBM System z hosts. + +- Linux MIPS64 (linux_mips64) : 64-bit Linux for MIPS architecture. + +- Linux MIPS64LE (linux_mips64le) : Suitable for 64-bit Linux systems with little endian MIPS architecture. + + + +## examples +Scripts to perform various build, install, analysis, etc operations. + +These scripts keep the root level Makefile small and simple. + +Examples: + +* https://github.com/kubernetes/helm/tree/master/scripts +* https://github.com/cockroachdb/cockroach/tree/master/scripts +* https://github.com/hashicorp/terraform/tree/master/scripts \ No newline at end of file diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100755 index 0000000..196794b --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,507 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# shellcheck disable=SC2034 # Variables sourced in other scripts. + +# Common utilities, variables and checks for all build scripts. +set -o errexit +set -o nounset +set -o pipefail + +# Unset CDPATH, having it set messes up with script import paths +unset CDPATH + +USER_ID=$(id -u) +GROUP_ID=$(id -g) + +DOCKER_OPTS=${DOCKER_OPTS:-""} +IFS=" " read -r -a DOCKER <<< "docker ${DOCKER_OPTS}" +DOCKER_HOST=${DOCKER_HOST:-""} +DOCKER_MACHINE_NAME=${DOCKER_MACHINE_NAME:-"openim-dev"} +readonly DOCKER_MACHINE_DRIVER=${DOCKER_MACHINE_DRIVER:-"virtualbox --virtualbox-cpu-count -1"} + +# This will canonicalize the path +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P) + +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# Constants +readonly OPENIM_BUILD_IMAGE_REPO=openim-build +#readonly OPENIM_BUILD_IMAGE_CROSS_TAG="$(cat "${OPENIM_ROOT}/build/build-image/cross/VERSION")" + +readonly OPENIM_DOCKER_REGISTRY="${OPENIM_DOCKER_REGISTRY:-k8s.gcr.io}" +readonly OPENIM_BASE_IMAGE_REGISTRY="${OPENIM_BASE_IMAGE_REGISTRY:-us.gcr.io/k8s-artifacts-prod/build-image}" + +# This version number is used to cause everyone to rebuild their data containers +# and build image. This is especially useful for automated build systems like +# Jenkins. +# +# Increment/change this number if you change the build image (anything under +# build/build-image) or change the set of volumes in the data container. +#readonly OPENIM_BUILD_IMAGE_VERSION_BASE="$(cat "${OPENIM_ROOT}/build/build-image/VERSION")" +#readonly OPENIM_BUILD_IMAGE_VERSION="${OPENIM_BUILD_IMAGE_VERSION_BASE}-${OPENIM_BUILD_IMAGE_CROSS_TAG}" + +# Here we map the output directories across both the local and remote _output +# directories: +# +# *_OUTPUT_ROOT - the base of all output in that environment. +# *_OUTPUT_SUBPATH - location where golang stuff is built/cached. Also +# persisted across docker runs with a volume mount. +# *_OUTPUT_BINPATH - location where final binaries are placed. If the remote +# is really remote, this is the stuff that has to be copied +# back. +# OUT_DIR can come in from the Makefile, so honor it. +readonly LOCAL_OUTPUT_ROOT="${OPENIM_ROOT}/${OUT_DIR:-_output}" +readonly LOCAL_OUTPUT_SUBPATH="${LOCAL_OUTPUT_ROOT}/platforms" +readonly LOCAL_OUTPUT_BINPATH="${LOCAL_OUTPUT_SUBPATH}" +readonly LOCAL_OUTPUT_GOPATH="${LOCAL_OUTPUT_SUBPATH}/go" +readonly LOCAL_OUTPUT_IMAGE_STAGING="${LOCAL_OUTPUT_ROOT}/images" + +# This is the port on the workstation host to expose RSYNC on. Set this if you +# are doing something fancy with ssh tunneling. +readonly OPENIM_RSYNC_PORT="${OPENIM_RSYNC_PORT:-}" + +# This is the port that rsync is running on *inside* the container. This may be +# mapped to OPENIM_RSYNC_PORT via docker networking. +readonly OPENIM_CONTAINER_RSYNC_PORT=8730 + +# Get the set of master binaries that run in Docker (on Linux) +# Entry format is ",". +# Binaries are placed in /usr/local/bin inside the image. +# +# $1 - server architecture +openim::build::get_docker_wrapped_binaries() { + local arch=$1 + local debian_base_version=v2.1.0 + local debian_iptables_version=v12.1.0 + ### If you change any of these lists, please also update DOCKERIZED_BINARIES + ### in build/BUILD. And openim::golang::server_image_targets + local targets=( + "openim-apiserver,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" + "openim-controller-manager,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" + "openim-scheduler,${OPENIM_BASE_IMAGE_REGISTRY}/debian-base-${arch}:${debian_base_version}" + "openim-proxy,${OPENIM_BASE_IMAGE_REGISTRY}/debian-iptables-${arch}:${debian_iptables_version}" + ) + + echo "${targets[@]}" +} + +# --------------------------------------------------------------------------- +# Basic setup functions + +# Verify that the right utilities and such are installed for building openim. Set +# up some dynamic constants. +# Args: +# $1 - boolean of whether to require functioning docker (default true) +# +# Vars set: +# OPENIM_ROOT_HASH +# OPENIM_BUILD_IMAGE_TAG_BASE +# OPENIM_BUILD_IMAGE_TAG +# OPENIM_BUILD_IMAGE +# OPENIM_BUILD_CONTAINER_NAME_BASE +# OPENIM_BUILD_CONTAINER_NAME +# OPENIM_DATA_CONTAINER_NAME_BASE +# OPENIM_DATA_CONTAINER_NAME +# OPENIM_RSYNC_CONTAINER_NAME_BASE +# OPENIM_RSYNC_CONTAINER_NAME +# DOCKER_MOUNT_ARGS +# LOCAL_OUTPUT_BUILD_CONTEXT +function openim::build::verify_prereqs() { + local -r require_docker=${1:-true} + openim::log::status "Verifying Prerequisites...." + openim::build::ensure_tar || return 1 + openim::build::ensure_rsync || return 1 + if ${require_docker}; then + openim::build::ensure_docker_in_path || return 1 + openim::util::ensure_docker_daemon_connectivity || return 1 + + if (( OPENIM_VERBOSE > 3 )); then + openim::log::status "Docker Version:" + "${DOCKER[@]}" version | openim::log::info_from_stdin + fi + fi + + OPENIM_GIT_BRANCH=$(git symbolic-ref --short -q HEAD 2>/dev/null || true) + OPENIM_ROOT_HASH=$(openim::build::short_hash "${HOSTNAME:-}:${OPENIM_ROOT}:${OPENIM_GIT_BRANCH}") + OPENIM_BUILD_IMAGE_TAG_BASE="build-${OPENIM_ROOT_HASH}" + #OPENIM_BUILD_IMAGE_TAG="${OPENIM_BUILD_IMAGE_TAG_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" + #OPENIM_BUILD_IMAGE="${OPENIM_BUILD_IMAGE_REPO}:${OPENIM_BUILD_IMAGE_TAG}" + OPENIM_BUILD_CONTAINER_NAME_BASE="openim-build-${OPENIM_ROOT_HASH}" + #OPENIM_BUILD_CONTAINER_NAME="${OPENIM_BUILD_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" + OPENIM_RSYNC_CONTAINER_NAME_BASE="openim-rsync-${OPENIM_ROOT_HASH}" + #OPENIM_RSYNC_CONTAINER_NAME="${OPENIM_RSYNC_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" + OPENIM_DATA_CONTAINER_NAME_BASE="openim-build-data-${OPENIM_ROOT_HASH}" + #OPENIM_DATA_CONTAINER_NAME="${OPENIM_DATA_CONTAINER_NAME_BASE}-${OPENIM_BUILD_IMAGE_VERSION}" + #DOCKER_MOUNT_ARGS=(--volumes-from "${OPENIM_DATA_CONTAINER_NAME}") + #LOCAL_OUTPUT_BUILD_CONTEXT="${LOCAL_OUTPUT_IMAGE_STAGING}/${OPENIM_BUILD_IMAGE}" + + openim::version::get_version_vars + #openim::version::save_version_vars "${OPENIM_ROOT}/.dockerized-openim-version-defs" +} + +# --------------------------------------------------------------------------- +# Utility functions + +function openim::build::docker_available_on_osx() { + if [[ -z "${DOCKER_HOST}" ]]; then + if [[ -S "/var/run/docker.sock" ]]; then + openim::log::status "Using Docker for MacOS" + return 0 + fi + + openim::log::status "No docker host is set. Checking options for setting one..." + if [[ -z "$(which docker-machine)" ]]; then + openim::log::status "It looks like you're running Mac OS X, yet neither Docker for Mac nor docker-machine can be found." + openim::log::status "See: https://docs.docker.com/engine/installation/mac/ for installation instructions." + return 1 + elif [[ -n "$(which docker-machine)" ]]; then + openim::build::prepare_docker_machine + fi + fi +} + +function openim::build::prepare_docker_machine() { + openim::log::status "docker-machine was found." + + local available_memory_bytes + available_memory_bytes=$(sysctl -n hw.memsize 2>/dev/null) + + local bytes_in_mb=1048576 + + # Give virtualbox 1/2 the system memory. Its necessary to divide by 2, instead + # of multiple by .5, because bash can only multiply by ints. + local memory_divisor=2 + + local virtualbox_memory_mb=$(( available_memory_bytes / (bytes_in_mb * memory_divisor) )) + + docker-machine inspect "${DOCKER_MACHINE_NAME}" &> /dev/null || { + openim::log::status "Creating a machine to build IAM" + docker-machine create --driver "${DOCKER_MACHINE_DRIVER}" \ + --virtualbox-memory "${virtualbox_memory_mb}" \ + --engine-env HTTP_PROXY="${IAMRNETES_HTTP_PROXY:-}" \ + --engine-env HTTPS_PROXY="${IAMRNETES_HTTPS_PROXY:-}" \ + --engine-env NO_PROXY="${IAMRNETES_NO_PROXY:-127.0.0.1}" \ + "${DOCKER_MACHINE_NAME}" > /dev/null || { + openim::log::error "Something went wrong creating a machine." + openim::log::error "Try the following: " + openim::log::error "docker-machine create -d ${DOCKER_MACHINE_DRIVER} --virtualbox-memory ${virtualbox_memory_mb} ${DOCKER_MACHINE_NAME}" + return 1 + } + } + docker-machine start "${DOCKER_MACHINE_NAME}" &> /dev/null + # it takes `docker-machine env` a few seconds to work if the machine was just started + local docker_machine_out + while ! docker_machine_out=$(docker-machine env "${DOCKER_MACHINE_NAME}" 2>&1); do + if [[ ${docker_machine_out} =~ "Error checking TLS connection" ]]; then + echo "${docker_machine_out}" + docker-machine regenerate-certs "${DOCKER_MACHINE_NAME}" + else + sleep 1 + fi + done + eval "$(docker-machine env "${DOCKER_MACHINE_NAME}")" + openim::log::status "A Docker host using docker-machine named '${DOCKER_MACHINE_NAME}' is ready to go!" + return 0 +} + +function openim::build::is_gnu_sed() { + [[ $(sed --version 2>&1) == *GNU* ]] +} + +function openim::build::ensure_rsync() { + if [[ -z "$(which rsync)" ]]; then + openim::log::error "Can't find 'rsync' in PATH, please fix and retry." + return 1 + fi +} + +function openim::build::update_dockerfile() { + if openim::build::is_gnu_sed; then + sed_opts=(-i) + else + sed_opts=(-i '') + fi + sed "${sed_opts[@]}" "s/OPENIM_BUILD_IMAGE_CROSS_TAG/${OPENIM_BUILD_IMAGE_CROSS_TAG}/" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" +} + +function openim::build::set_proxy() { + if [[ -n "${IAMRNETES_HTTPS_PROXY:-}" ]]; then + echo "ENV https_proxy $IAMRNETES_HTTPS_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" + fi + if [[ -n "${IAMRNETES_HTTP_PROXY:-}" ]]; then + echo "ENV http_proxy $IAMRNETES_HTTP_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" + fi + if [[ -n "${IAMRNETES_NO_PROXY:-}" ]]; then + echo "ENV no_proxy $IAMRNETES_NO_PROXY" >> "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" + fi +} + +function openim::build::ensure_docker_in_path() { + if [[ -z "$(which docker)" ]]; then + openim::log::error "Can't find 'docker' in PATH, please fix and retry." + openim::log::error "See https://docs.docker.com/installation/#installation for installation instructions." + return 1 + fi +} + +function openim::build::ensure_tar() { + if [[ -n "${TAR:-}" ]]; then + return + fi + + # Find gnu tar if it is available, bomb out if not. + TAR=tar + if which gtar &>/dev/null; then + TAR=gtar + else + if which gnutar &>/dev/null; then + TAR=gnutar + fi + fi + if ! "${TAR}" --version | grep -q GNU; then + echo " !!! Cannot find GNU tar. Build on Linux or install GNU tar" + echo " on Mac OS X (brew install gnu-tar)." + return 1 + fi +} + +function openim::build::has_docker() { + which docker &> /dev/null +} + +function openim::build::has_ip() { + which ip &> /dev/null && ip -Version | grep 'iproute2' &> /dev/null +} + +# Detect if a specific image exists +# +# $1 - image repo name +# $2 - image tag +function openim::build::docker_image_exists() { + [[ -n $1 && -n $2 ]] || { + openim::log::error "Internal error. Image not specified in docker_image_exists." + exit 2 + } + + [[ $("${DOCKER[@]}" images -q "${1}:${2}") ]] +} + +# Delete all images that match a tag prefix except for the "current" version +# +# $1: The image repo/name +# $2: The tag base. We consider any image that matches $2* +# $3: The current image not to delete if provided +function openim::build::docker_delete_old_images() { + # In Docker 1.12, we can replace this with + # docker images "$1" --format "{{.Tag}}" + for tag in $("${DOCKER[@]}" images "${1}" | tail -n +2 | awk '{print $2}') ; do + if [[ "${tag}" != "${2}"* ]] ; then + V=3 openim::log::status "Keeping image ${1}:${tag}" + continue + fi + + if [[ -z "${3:-}" || "${tag}" != "${3}" ]] ; then + V=2 openim::log::status "Deleting image ${1}:${tag}" + "${DOCKER[@]}" rmi "${1}:${tag}" >/dev/null + else + V=3 openim::log::status "Keeping image ${1}:${tag}" + fi + done +} + +# Stop and delete all containers that match a pattern +# +# $1: The base container prefix +# $2: The current container to keep, if provided +function openim::build::docker_delete_old_containers() { + # In Docker 1.12 we can replace this line with + # docker ps -a --format="{{.Names}}" + for container in $("${DOCKER[@]}" ps -a | tail -n +2 | awk '{print $NF}') ; do + if [[ "${container}" != "${1}"* ]] ; then + V=3 openim::log::status "Keeping container ${container}" + continue + fi + if [[ -z "${2:-}" || "${container}" != "${2}" ]] ; then + V=2 openim::log::status "Deleting container ${container}" + openim::build::destroy_container "${container}" + else + V=3 openim::log::status "Keeping container ${container}" + fi + done +} + +# Takes $1 and computes a short has for it. Useful for unique tag generation +function openim::build::short_hash() { + [[ $# -eq 1 ]] || { + openim::log::error "Internal error. No data based to short_hash." + exit 2 + } + + local short_hash + if which md5 >/dev/null 2>&1; then + short_hash=$(md5 -q -s "$1") + else + short_hash=$(echo -n "$1" | md5sum) + fi + echo "${short_hash:0:10}" +} + +# Pedantically kill, wait-on and remove a container. The -f -v options +# to rm don't actually seem to get the job done, so force kill the +# container, wait to ensure it's stopped, then try the remove. This is +# a workaround for bug https://github.com/docker/docker/issues/3968. +function openim::build::destroy_container() { + "${DOCKER[@]}" kill "$1" >/dev/null 2>&1 || true + if [[ $("${DOCKER[@]}" version --format '{{.Server.Version}}') = 17.06.0* ]]; then + # Workaround https://github.com/moby/moby/issues/33948. + # TODO: remove when 17.06.0 is not relevant anymore + DOCKER_API_VERSION=v1.29 "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true + else + "${DOCKER[@]}" wait "$1" >/dev/null 2>&1 || true + fi + "${DOCKER[@]}" rm -f -v "$1" >/dev/null 2>&1 || true +} + +# --------------------------------------------------------------------------- +# Building + + +function openim::build::clean() { + if openim::build::has_docker ; then + openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}" + openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}" + openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}" + openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" + + V=2 openim::log::status "Cleaning all untagged docker images" + "${DOCKER[@]}" rmi "$("${DOCKER[@]}" images -q --filter 'dangling=true')" 2> /dev/null || true + fi + + if [[ -d "${LOCAL_OUTPUT_ROOT}" ]]; then + openim::log::status "Removing _output directory" + rm -rf "${LOCAL_OUTPUT_ROOT}" + fi +} + +# Set up the context directory for the openim-build image and build it. +function openim::build::build_image() { + mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}" + # Make sure the context directory owned by the right user for syncing sources to container. + chown -R "${USER_ID}":"${GROUP_ID}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" + + cp /etc/localtime "${LOCAL_OUTPUT_BUILD_CONTEXT}/" + + cp "${OPENIM_ROOT}/build/build-image/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile" + cp "${OPENIM_ROOT}/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/" + dd if=/dev/urandom bs=512 count=1 2>/dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | dd bs=32 count=1 2>/dev/null > "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password" + chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password" + + openim::build::update_dockerfile + openim::build::set_proxy + openim::build::docker_build "${OPENIM_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false' + + # Clean up old versions of everything + openim::build::docker_delete_old_containers "${OPENIM_BUILD_CONTAINER_NAME_BASE}" "${OPENIM_BUILD_CONTAINER_NAME}" + openim::build::docker_delete_old_containers "${OPENIM_RSYNC_CONTAINER_NAME_BASE}" "${OPENIM_RSYNC_CONTAINER_NAME}" + openim::build::docker_delete_old_containers "${OPENIM_DATA_CONTAINER_NAME_BASE}" "${OPENIM_DATA_CONTAINER_NAME}" + openim::build::docker_delete_old_images "${OPENIM_BUILD_IMAGE_REPO}" "${OPENIM_BUILD_IMAGE_TAG_BASE}" "${OPENIM_BUILD_IMAGE_TAG}" + + openim::build::ensure_data_container + openim::build::sync_to_container +} + +# Build a docker image from a Dockerfile. +# $1 is the name of the image to build +# $2 is the location of the "context" directory, with the Dockerfile at the root. +# $3 is the value to set the --pull flag for docker build; true by default +function openim::build::docker_build() { + local -r image=$1 + local -r context_dir=$2 + local -r pull="${3:-true}" + local -ra build_cmd=("${DOCKER[@]}" build -t "${image}" "--pull=${pull}" "${context_dir}") + + openim::log::status "Building Docker image ${image}" + local docker_output + docker_output=$("${build_cmd[@]}" 2>&1) || { + cat <&2 ++++ Docker build command failed for ${image} + +${docker_output} + +To retry manually, run: + +${build_cmd[*]} + +EOF + return 1 + } +} + +function openim::build::ensure_data_container() { + # If the data container exists AND exited successfully, we can use it. + # Otherwise nuke it and start over. + local ret=0 + local code=0 + + code=$(docker inspect \ + -f '{{.State.ExitCode}}' \ + "${OPENIM_DATA_CONTAINER_NAME}" 2>/dev/null) || ret=$? + if [[ "${ret}" == 0 && "${code}" != 0 ]]; then + openim::build::destroy_container "${OPENIM_DATA_CONTAINER_NAME}" + ret=1 + fi + if [[ "${ret}" != 0 ]]; then + openim::log::status "Creating data container ${OPENIM_DATA_CONTAINER_NAME}" + # We have to ensure the directory exists, or else the docker run will + # create it as root. + mkdir -p "${LOCAL_OUTPUT_GOPATH}" + # We want this to run as root to be able to chown, so non-root users can + # later use the result as a data container. This run both creates the data + # container and chowns the GOPATH. + # + # The data container creates volumes for all of the directories that store + # intermediates for the Go build. This enables incremental builds across + # Docker sessions. The *_cgo paths are re-compiled versions of the go std + # libraries for true static building. + local -ra docker_cmd=( + "${DOCKER[@]}" run + --volume "${REMOTE_ROOT}" # white-out the whole output dir + --volume /usr/local/go/pkg/linux_386_cgo + --volume /usr/local/go/pkg/linux_amd64_cgo + --volume /usr/local/go/pkg/linux_arm_cgo + --volume /usr/local/go/pkg/linux_arm64_cgo + --volume /usr/local/go/pkg/linux_ppc64le_cgo + --volume /usr/local/go/pkg/darwin_amd64_cgo + --volume /usr/local/go/pkg/darwin_386_cgo + --volume /usr/local/go/pkg/windows_amd64_cgo + --volume /usr/local/go/pkg/windows_386_cgo + --name "${OPENIM_DATA_CONTAINER_NAME}" + --hostname "${HOSTNAME}" + "${OPENIM_BUILD_IMAGE}" + chown -R "${USER_ID}":"${GROUP_ID}" + "${REMOTE_ROOT}" + /usr/local/go/pkg/ + ) + "${docker_cmd[@]}" + fi +} + +# Build all openim commands. +function openim::build::build_command() { + openim::log::status "Running build command..." + make -C "${OPENIM_ROOT}" build.multiarch BINS="openimctl openim-apiserver openim-authz-server openim-pump openim-watcher" +} diff --git a/scripts/coverage.awk b/scripts/coverage.awk new file mode 100755 index 0000000..4938905 --- /dev/null +++ b/scripts/coverage.awk @@ -0,0 +1,13 @@ +#!/usr/bin/env awk + +{ + print $0 + if (match($0, /^total:/)) { + sub(/%/, "", $NF); + printf("test coverage is %s%(quality gate is %s%)\n", $NF, target) + if (strtonum($NF) < target) { + printf("test coverage does not meet expectations: %d%, please add test cases!\n", target) + exit 1; + } + } +} diff --git a/scripts/ensure_tag.sh b/scripts/ensure_tag.sh new file mode 100755 index 0000000..c6fea7c --- /dev/null +++ b/scripts/ensure_tag.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version="${VERSION}" +if [ "${version}" == "" ];then + version=v`gsemver bump` +fi + +if [ -z "`git tag -l ${version}`" ];then + git tag -a -m "release version ${version}" ${version} +fi diff --git a/scripts/githooks/commit-msg.sh b/scripts/githooks/commit-msg.sh new file mode 100644 index 0000000..a0030c9 --- /dev/null +++ b/scripts/githooks/commit-msg.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 aicworld. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============================================================================== +# +# Store this file as .git/hooks/commit-msg in your repository in order to +# enforce checking for proper commit message format before actual commits. +# You may need to make the scripts executable by 'chmod +x .git/hooks/commit-msg'. + +# commit-msg use go-gitlint tool, install go-gitlint via `go get github.com/llorllale/go-gitlint/cmd/go-gitlint` +# go-gitlint --msg-file="$1" + +# An example hook scripts to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. + +YELLOW="\e[93m" +GREEN="\e[32m" +RED="\e[31m" +ENDCOLOR="\e[0m" + +printMessage() { + printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" +} + +printSuccess() { + printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" +} + +printError() { + printf "${RED}OpenIM : $1${ENDCOLOR}\n" +} + +printMessage "Running the OpenIM commit-msg hook." + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} + +# TODO: go-gitlint dir set +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/../.. +GITLINT_DIR="$OPENIM_ROOT/_output/tools/go-gitlint" + +$GITLINT_DIR \ + --msg-file=$1 \ + --subject-regex="^(build|chore|ci|docs|feat|feature|fix|perf|refactor|revert|style|test)(.*)?:\s?.*" \ + --subject-maxlen=150 \ + --subject-minlen=10 \ + --body-regex=".*" \ + --max-parents=1 + +if [ $? -ne 0 ] +then + if ! command -v $GITLINT_DIR &>/dev/null; then + printError "$GITLINT_DIR not found. Please run 'make tools' OR 'make tools.verify.go-gitlint' make verto install it." + fi + printError "Please fix your commit message to match kubecub coding standards" + printError "https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md" + exit 1 +fi + +### Add Sign-off-by line to the end of the commit message +# Get local git config +NAME=$(git config user.name) +EMAIL=$(git config user.email) + +# Check if the commit message contains a sign-off line +grep -qs "^Signed-off-by: " "$1" +SIGNED_OFF_BY_EXISTS=$? + +# Add "Signed-off-by" line if it doesn't exist +if [ $SIGNED_OFF_BY_EXISTS -ne 0 ]; then + echo -e "\nSigned-off-by: $NAME <$EMAIL>" >> "$1" +fi \ No newline at end of file diff --git a/scripts/githooks/pre-commit.sh b/scripts/githooks/pre-commit.sh new file mode 100644 index 0000000..87c51ed --- /dev/null +++ b/scripts/githooks/pre-commit.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 aicworld. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============================================================================== +# This is a pre-commit hook that ensures attempts to commit files that are +# are larger than $limit to your _local_ repo fail, with a helpful error message. + +# You can override the default limit of 2MB by supplying the environment variable: +# GIT_FILE_SIZE_LIMIT=50000000 git commit -m "test: this commit is allowed file sizes up to 50MB" +# +# ============================================================================== +# + +LC_ALL=C + +local_branch="$(git rev-parse --abbrev-ref HEAD)" +valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" + +YELLOW="\e[93m" +GREEN="\e[32m" +RED="\e[31m" +ENDCOLOR="\e[0m" + +printMessage() { + printf "${YELLOW}openim : $1${ENDCOLOR}\n" +} + +printSuccess() { + printf "${GREEN}openim : $1${ENDCOLOR}\n" +} + +printError() { + printf "${RED}openim : $1${ENDCOLOR}\n" +} + +printMessage "Running local openim pre-commit hook." + +# flutter format . +# https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md +# TODO! GIT_FILE_SIZE_LIMIT=50000000 git commit -m "test: this commit is allowed file sizes up to 50MB" +# Maximum file size limit in bytes +limit=${GIT_FILE_SIZE_LIMIT:-2000000} # Default 2MB +limitInMB=$(( $limit / 1000000 )) + +function file_too_large(){ + filename=$0 + filesize=$(( $1 / 2**20 )) + + cat < /dev/null 2>&1 +then + against=HEAD +else + against="$empty_tree" +fi + +# Set split so that for loop below can handle spaces in file names by splitting on line breaks +IFS=' +' + +shouldFail=false +for file in $( git diff-index --cached --name-only $against ); do + file_size=$(([ ! -f $file ] && echo 0) || (ls -la $file | awk '{ print $5 }')) + if [ "$file_size" -gt "$limit" ]; then + printError "File $file is $(( $file_size / 10**6 )) MB, which is larger than our configured limit of $limitInMB MB" + shouldFail=true + fi +done + +if $shouldFail +then + printMessage "If you really need to commit this file, you can override the size limit by setting the GIT_FILE_SIZE_LIMIT environment variable, e.g. GIT_FILE_SIZE_LIMIT=42000000 for 42MB. Or, commit with the --no-verify switch to skip the check entirely." + printError "Commit aborted" + exit 1; +fi + +if [[ ! $local_branch =~ $valid_branch_regex ]] +then + printError "There is something wrong with your branch name. Branch names in this project must adhere to this contract: $valid_branch_regex. +Your commit will be rejected. You should rename your branch to a valid name(feat/name OR bug/name) and try again." + printError "For more on this, read on: https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694" + exit 1 +fi \ No newline at end of file diff --git a/scripts/githooks/pre-push.sh b/scripts/githooks/pre-push.sh new file mode 100644 index 0000000..dee87a2 --- /dev/null +++ b/scripts/githooks/pre-push.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 aicworld. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============================================================================== +# + +YELLOW="\e[93m" +GREEN="\e[32m" +RED="\e[31m" +ENDCOLOR="\e[0m" + +local_branch="$(git rev-parse --abbrev-ref HEAD)" +valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" + +printMessage() { + printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" +} + +printSuccess() { + printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" +} + +printError() { + printf "${RED}OpenIM : $1${ENDCOLOR}\n" +} + +printMessage "Running local OpenIM pre-push hook." + +if [[ `git status --porcelain` ]]; then + printError "This scripts needs to run against committed code only. Please commit or stash you changes." + exit 1 +fi + +COLOR_SUFFIX="\033[0m" + +BLACK_PREFIX="\033[30m" +RED_PREFIX="\033[31m" +GREEN_PREFIX="\033[32m" +BACKGROUND_GREEN="\033[33m" +BLUE_PREFIX="\033[34m" +PURPLE_PREFIX="\033[35m" +SKY_BLUE_PREFIX="\033[36m" +WHITE_PREFIX="\033[37m" +BOLD_PREFIX="\033[1m" +UNDERLINE_PREFIX="\033[4m" +ITALIC_PREFIX="\033[3m" + +# Function to print colored text +print_color() { + local text=$1 + local color=$2 + echo -e "${color}${text}${COLOR_SUFFIX}" +} + +# Function to print section separator +print_separator() { + print_color "==========================================================" ${PURPLE_PREFIX} +} + +# Get current time +time=$(date +"%Y-%m-%d %H:%M:%S") + +# Print section separator +print_separator + +# Print time of submission +print_color "PTIME: ${time}" "${BOLD_PREFIX}${CYAN_PREFIX}" +echo "" +author=$(git config user.name) +repository=$(basename -s .git $(git config --get remote.origin.url)) + +# Print additional information if needed +print_color "Repository: ${repository}" "${BLUE_PREFIX}" +echo "" + +print_color "Author: ${author}" "${PURPLE_PREFIX}" + +# Print section separator +print_separator + +file_list=$(git diff --name-status HEAD @{u}) +added_files=$(grep -c '^A' <<< "$file_list") +modified_files=$(grep -c '^M' <<< "$file_list") +deleted_files=$(grep -c '^D' <<< "$file_list") + +print_color "Added Files: ${added_files}" "${BACKGROUND_GREEN}" +print_color "Modified Files: ${modified_files}" "${BACKGROUND_GREEN}" +print_color "Deleted Files: ${deleted_files}" "${BACKGROUND_GREEN}" + +if [[ ! $local_branch =~ $valid_branch_regex ]] +then + printError "There is something wrong with your branch name. Branch names in this project must adhere to this contract: $valid_branch_regex. +Your commit will be rejected. You should rename your branch to a valid name(feat/name OR bug/name) and try again." + printError "For more on this, read on: https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694" + exit 1 +fi + +# +#printMessage "Running the Flutter analyzer" +#flutter analyze +# +#if [ $? -ne 0 ]; then +# printError "Flutter analyzer error" +# exit 1 +#fi +# +#printMessage "Finished running the Flutter analyzer" diff --git a/scripts/init-githooks.sh b/scripts/init-githooks.sh new file mode 100755 index 0000000..399054b --- /dev/null +++ b/scripts/init-githooks.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ----------------------------------------------------------------------------- +# init-githooks.sh +# +# This script assists in managing Git hooks for the OpenIM project. +# When executed: +# 1. It prompts the user to enable git hooks. +# 2. If the user accepts, it copies predefined hook scripts to the appropriate +# Git directory, making them executable. +# 3. If requested, it can delete the added hooks. +# +# This script equal runs `make init-githooks` command. +# Usage: +# ./init-githooks.sh Prompt to enable git hooks. +# ./init-githooks.sh --delete Delete previously added git hooks. +# ./init-githooks.sh --help Show the help message. +# +# Example: `scripts/build-go.sh --help`. +# Documentation & related context can be found at: +# https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694 +# +# ----------------------------------------------------------------------------- + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +HOOKS_DIR="${OPENIM_ROOT}/.git/hooks" + +help_info() { + echo "Usage: $0 [options]" + echo + echo "This script helps to manage git hooks." + echo + echo "Options:" + echo " -h, --help Show this help message and exit." + echo " -d, --delete Delete the hooks that have been added." + echo " By default, it will prompt to enable git hooks." +} + +delete_hooks() { + for file in ${OPENIM_ROOT}/scripts/githooks/*.sh; do + hook_name=$(basename "$file" .sh) # This removes the .sh extension + rm -f "$HOOKS_DIR/$hook_name" + done + echo "Git hooks have been deleted." +} + +enable_hooks() { + echo "Would you like to:" + echo "1) Enable git hooks mode" + echo "2) Delete existing git hooks" + echo "Please select a number (or any other key to exit):" + read -r choice + + case "$choice" in + 1) + for file in ${OPENIM_ROOT}/scripts/githooks/*.sh; do + hook_name=$(basename "$file" .sh) # This removes the .sh extension + cp -f "$file" "$HOOKS_DIR/$hook_name" + done + + chmod +x $HOOKS_DIR/* + + echo "Git hooks mode has been enabled." + echo "With git hooks enabled, every time you perform a git action (e.g. git commit), the corresponding hooks script will be triggered automatically." + echo "This means that if the size of the file you're committing exceeds the set limit (e.g. 42MB), the commit will be rejected." + ;; + 2) + delete_hooks + ;; + *) + echo "Exiting without making changes." + ;; + esac +} + + +case "$1" in + -h|--help) + help_info + ;; + -d|--delete) + delete_hooks + ;; + *) + enable_hooks + ;; +esac diff --git a/scripts/lib/color.sh b/scripts/lib/color.sh new file mode 100755 index 0000000..52caa78 --- /dev/null +++ b/scripts/lib/color.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +#Define color variables +#Feature +COLOR_NORMAL='\033[0m';COLOR_BOLD='\033[1m';COLOR_DIM='\033[2m';COLOR_UNDER='\033[4m'; +COLOR_ITALIC='\033[3m';COLOR_NOITALIC='\033[23m';COLOR_BLINK='\033[5m'; +COLOR_REVERSE='\033[7m';COLOR_CONCEAL='\033[8m';COLOR_NOBOLD='\033[22m'; +COLOR_NOUNDER='\033[24m';COLOR_NOBLINK='\033[25m'; + +#Front color +COLOR_BLACK='\033[30m';COLOR_RED='\033[31m';COLOR_GREEN='\033[32m';COLOR_YELLOW='\033[33m'; +COLOR_BLUE='\033[34m';COLOR_MAGENTA='\033[35m';COLOR_CYAN='\033[36m';COLOR_WHITE='\033[37m'; + +#background color +COLOR_BBLACK='\033[40m';COLOR_BRED='\033[41m'; +COLOR_BGREEN='\033[42m';COLOR_BYELLOW='\033[43m'; +COLOR_BBLUE='\033[44m';COLOR_BMAGENTA='\033[45m'; +COLOR_BCYAN='\033[46m';COLOR_BWHITE='\033[47m'; + +# Print colors you can use +openim::color::print_color() +{ + echo + echo -e ${bmagenta}--back-color:${normal} + echo "bblack; bgreen; bblue; bcyan; bred; byellow; bmagenta; bwhite" + echo + echo -e ${red}--font-color:${normal} + echo "black; red; green; yellow; blue; magenta; cyan; white" + echo + echo -e ${bold}--font:${normal} + echo "normal; italic; reverse; nounder; bold; noitalic; conceal; noblink; + dim; blink; nobold; under" + echo +} diff --git a/scripts/lib/golang.sh b/scripts/lib/golang.sh new file mode 100755 index 0000000..9f86aec --- /dev/null +++ b/scripts/lib/golang.sh @@ -0,0 +1,214 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# shellcheck disable=SC2034 # Variables sourced in other scripts. + +# The server platform we are building on. +readonly OPENIM_SUPPORTED_SERVER_PLATFORMS=( + linux_s390x + linux_mips64 + linux_mips64le + darwin_amd64 + windows_amd64 + linux_amd64 + linux_arm64 +) + +# If we update this we should also update the set of platforms whose standard +# library is precompiled for in build/build-image/cross/Dockerfile +readonly OPENIM_SUPPORTED_CLIENT_PLATFORMS=( + linux_s390x + linux_mips64 + linux_mips64le + darwin_amd64 + windows_amd64 + linux_amd64 + linux_arm64 +) + +# The set of server targets that we are only building for Linux +# If you update this list, please also update build/BUILD. +openim::golang::server_targets() { + local targets=( + openim-apiserver + openim-authz-server + openim-pump + openim-watcher + ) + echo "${targets[@]}" +} + +IFS=" " read -ra OPENIM_SERVER_TARGETS <<< "$(openim::golang::server_targets)" +readonly OPENIM_SERVER_TARGETS +readonly OPENIM_SERVER_BINARIES=("${OPENIM_SERVER_TARGETS[@]##*/}") + +# The set of server targets we build docker images for +openim::golang::server_image_targets() { + # NOTE: this contains cmd targets for openim::build::get_docker_wrapped_binaries + local targets=( + cmd/openim-apiserver + cmd/openim-authz-server + cmd/openim-pump + cmd/openim-watcher + ) + echo "${targets[@]}" +} + +IFS=" " read -ra OPENIM_SERVER_IMAGE_TARGETS <<< "$(openim::golang::server_image_targets)" +readonly OPENIM_SERVER_IMAGE_TARGETS +readonly OPENIM_SERVER_IMAGE_BINARIES=("${OPENIM_SERVER_IMAGE_TARGETS[@]##*/}") + +# ------------ +# NOTE: All functions that return lists should use newlines. +# bash functions can't return arrays, and spaces are tricky, so newline +# separators are the preferred pattern. +# To transform a string of newline-separated items to an array, use openim::util::read-array: +# openim::util::read-array FOO < <(openim::golang::dups a b c a) +# +# ALWAYS remember to quote your subshells. Not doing so will break in +# bash 4.3, and potentially cause other issues. +# ------------ + +# Returns a sorted newline-separated list containing only duplicated items. +openim::golang::dups() { + # We use printf to insert newlines, which are required by sort. + printf "%s\n" "$@" | sort | uniq -d +} + +# Returns a sorted newline-separated list with duplicated items removed. +openim::golang::dedup() { + # We use printf to insert newlines, which are required by sort. + printf "%s\n" "$@" | sort -u +} + +# Depends on values of user-facing OPENIM_BUILD_PLATFORMS, OPENIM_FASTBUILD, +# and OPENIM_BUILDER_OS. +# Configures OPENIM_SERVER_PLATFORMS and OPENIM_CLIENT_PLATFORMS, then sets them +# to readonly. +# The configured vars will only contain platforms allowed by the +# OPENIM_SUPPORTED* vars at the top of this file. +declare -a OPENIM_SERVER_PLATFORMS +declare -a OPENIM_CLIENT_PLATFORMS +openim::golang::setup_platforms() { + if [[ -n "${OPENIM_BUILD_PLATFORMS:-}" ]]; then + # OPENIM_BUILD_PLATFORMS needs to be read into an array before the next + # step, or quoting treats it all as one element. + local -a platforms + IFS=" " read -ra platforms <<< "${OPENIM_BUILD_PLATFORMS}" + + # Deduplicate to ensure the intersection trick with openim::golang::dups + # is not defeated by duplicates in user input. + openim::util::read-array platforms < <(openim::golang::dedup "${platforms[@]}") + + # Use openim::golang::dups to restrict the builds to the platforms in + # OPENIM_SUPPORTED_*_PLATFORMS. Items should only appear at most once in each + # set, so if they appear twice after the merge they are in the intersection. + openim::util::read-array OPENIM_SERVER_PLATFORMS < <(openim::golang::dups \ + "${platforms[@]}" \ + "${OPENIM_SUPPORTED_SERVER_PLATFORMS[@]}" \ + ) + readonly OPENIM_SERVER_PLATFORMS + + openim::util::read-array OPENIM_CLIENT_PLATFORMS < <(openim::golang::dups \ + "${platforms[@]}" \ + "${OPENIM_SUPPORTED_CLIENT_PLATFORMS[@]}" \ + ) + readonly OPENIM_CLIENT_PLATFORMS + + elif [[ "${OPENIM_FASTBUILD:-}" == "true" ]]; then + OPENIM_SERVER_PLATFORMS=(linux/amd64) + readonly OPENIM_SERVER_PLATFORMS + OPENIM_CLIENT_PLATFORMS=(linux/amd64) + readonly OPENIM_CLIENT_PLATFORMS + else + OPENIM_SERVER_PLATFORMS=("${OPENIM_SUPPORTED_SERVER_PLATFORMS[@]}") + readonly OPENIM_SERVER_PLATFORMS + + OPENIM_CLIENT_PLATFORMS=("${OPENIM_SUPPORTED_CLIENT_PLATFORMS[@]}") + readonly OPENIM_CLIENT_PLATFORMS + fi +} + +openim::golang::setup_platforms + +# The set of client targets that we are building for all platforms +# If you update this list, please also update build/BUILD. +readonly OPENIM_CLIENT_TARGETS=( + iamctl +) +readonly OPENIM_CLIENT_BINARIES=("${OPENIM_CLIENT_TARGETS[@]##*/}") + +readonly OPENIM_ALL_TARGETS=( + "${OPENIM_SERVER_TARGETS[@]}" + "${OPENIM_CLIENT_TARGETS[@]}" +) +readonly OPENIM_ALL_BINARIES=("${OPENIM_ALL_TARGETS[@]##*/}") + +# Asks golang what it thinks the host platform is. The go tool chain does some +# slightly different things when the target platform matches the host platform. +openim::golang::host_platform() { + echo "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" +} + +# Ensure the go tool exists and is a viable version. +openim::golang::verify_go_version() { + if [[ -z "$(command -v go)" ]]; then + openim::log::usage_from_stdin <&2 + local i + for ((i=1 ; i <= ${#FUNCNAME[@]} - stack_skip ; i++)) + do + local frame_no=$((i - 1 + stack_skip)) + local source_file=${BASH_SOURCE[${frame_no}]} + local source_lineno=${BASH_LINENO[$((frame_no - 1))]} + local funcname=${FUNCNAME[${frame_no}]} + echo " ${i}: ${source_file}:${source_lineno} ${funcname}(...)" >&2 + done + fi +} + +# Log an error and exit. +# Args: +# $1 Message to log with the error +# $2 The error code to return +# $3 The number of stack frames to skip when printing. +openim::log::error_exit() { + local message="${1:-}" + local code="${2:-1}" + local stack_skip="${3:-0}" + stack_skip=$((stack_skip + 1)) + + if [[ ${OPENIM_VERBOSE} -ge 4 ]]; then + local source_file=${BASH_SOURCE[${stack_skip}]} + local source_line=${BASH_LINENO[$((stack_skip - 1))]} + echo "!!! Error in ${source_file}:${source_line}" >&2 + [[ -z ${1-} ]] || { + echo " ${1}" >&2 + } + + openim::log::stack ${stack_skip} + + echo "Exiting with status ${code}" >&2 + fi + + exit "${code}" +} + +# Log an error but keep going. Don't dump the stack or exit. +openim::log::error() { + timestamp=$(date +"[%m%d %H:%M:%S]") + echo "!!! ${timestamp} ${1-}" >&2 + shift + for message; do + echo " ${message}" >&2 + done +} + +# Print an usage message to stderr. The arguments are printed directly. +openim::log::usage() { + echo >&2 + local message + for message; do + echo "${message}" >&2 + done + echo >&2 +} + +openim::log::usage_from_stdin() { + local messages=() + while read -r line; do + messages+=("${line}") + done + + openim::log::usage "${messages[@]}" +} + +# Print out some info that isn't a top level status line +openim::log::info() { + local V="${V:-0}" + if [[ ${OPENIM_VERBOSE} < ${V} ]]; then + return + fi + + for message; do + echo "${message}" + done +} + +# Just like openim::log::info, but no \n, so you can make a progress bar +openim::log::progress() { + for message; do + echo -e -n "${message}" + done +} + +openim::log::info_from_stdin() { + local messages=() + while read -r line; do + messages+=("${line}") + done + + openim::log::info "${messages[@]}" +} + +# Print a status line. Formatted to show up in a stream of output. +openim::log::status() { + local V="${V:-0}" + if [[ ${OPENIM_VERBOSE} < ${V} ]]; then + return + fi + + timestamp=$(date +"[%m%d %H:%M:%S]") + echo "+++ ${timestamp} ${1}" + shift + for message; do + echo " ${message}" + done +} diff --git a/scripts/lib/release.sh b/scripts/lib/release.sh new file mode 100755 index 0000000..baebbc9 --- /dev/null +++ b/scripts/lib/release.sh @@ -0,0 +1,616 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +############################################################################### +# Most of the ::release:: namespace functions have been moved to +# github.com/openim/release. Have a look in that repo and specifically in +# lib/releaselib.sh for ::release::-related functionality. +############################################################################### +# example: ./coscli cp/sync -r /home/off-line/docker-off-line/ cos://openim-1306374445/openim/image/amd/off-line/off-line/ -e cos.ap-guangzhou.myqcloud.com +# https://cloud.tencent.com/document/product/436/71763 + +# Tencent cos configuration +readonly BUCKET="openim-1306374445" +readonly REGION="ap-guangzhou" +readonly COS_RELEASE_DIR="openim-release" + +# default cos command tool coscli or coscmd +readonly COSTOOL="coscli" + +# This is where the final release artifacts are created locally +readonly RELEASE_STAGE="${LOCAL_OUTPUT_ROOT}/release-stage" +readonly RELEASE_TARS="${LOCAL_OUTPUT_ROOT}/release-tars" +readonly RELEASE_IMAGES="${LOCAL_OUTPUT_ROOT}/release-images" + +# OpenIM github account info +readonly OPENIM_GITHUB_ORG=aicworld +readonly OPENIM_GITHUB_REPO=Open-IM-Server + +readonly ARTIFACT=openim.tar.gz +readonly CHECKSUM=${ARTIFACT}.sha1sum + +OPENIM_BUILD_CONFORMANCE=${OPENIM_BUILD_CONFORMANCE:-y} +OPENIM_BUILD_PULL_LATEST_IMAGES=${OPENIM_BUILD_PULL_LATEST_IMAGES:-y} + +# Validate a ci version +# +# Globals: +# None +# Arguments: +# version +# Returns: +# If version is a valid ci version +# Sets: (e.g. for '1.2.3-alpha.4.56+abcdef12345678') +# VERSION_MAJOR (e.g. '1') +# VERSION_MINOR (e.g. '2') +# VERSION_PATCH (e.g. '3') +# VERSION_PRERELEASE (e.g. 'alpha') +# VERSION_PRERELEASE_REV (e.g. '4') +# VERSION_BUILD_INFO (e.g. '.56+abcdef12345678') +# VERSION_COMMITS (e.g. '56') +function openim::release::parse_and_validate_ci_version() { + # Accept things like "v1.2.3-alpha.4.56+abcdef12345678" or "v1.2.3-beta.4" + local -r version_regex="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-([a-zA-Z0-9]+)\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)\\+[0-9a-f]{7,40})?$" + local -r version="${1-}" + [[ "${version}" =~ ${version_regex} ]] || { + openim::log::error "Invalid ci version: '${version}', must match regex ${version_regex}" + return 1 + } + + # The VERSION variables are used when this file is sourced, hence + # the shellcheck SC2034 'appears unused' warning is to be ignored. + + # shellcheck disable=SC2034 + VERSION_MAJOR="${BASH_REMATCH[1]}" + # shellcheck disable=SC2034 + VERSION_MINOR="${BASH_REMATCH[2]}" + # shellcheck disable=SC2034 + VERSION_PATCH="${BASH_REMATCH[3]}" + # shellcheck disable=SC2034 + VERSION_PRERELEASE="${BASH_REMATCH[4]}" + # shellcheck disable=SC2034 + VERSION_PRERELEASE_REV="${BASH_REMATCH[5]}" + # shellcheck disable=SC2034 + VERSION_BUILD_INFO="${BASH_REMATCH[6]}" + # shellcheck disable=SC2034 + VERSION_COMMITS="${BASH_REMATCH[7]}" +} + +# --------------------------------------------------------------------------- +# Build final release artifacts +function openim::release::clean_cruft() { + # Clean out cruft + find "${RELEASE_STAGE}" -name '*~' -exec rm {} \; + find "${RELEASE_STAGE}" -name '#*#' -exec rm {} \; + find "${RELEASE_STAGE}" -name '.DS*' -exec rm {} \; +} + +function openim::release::package_tarballs() { + # Clean out any old releases + rm -rf "${RELEASE_STAGE}" "${RELEASE_TARS}" "${RELEASE_IMAGES}" + mkdir -p "${RELEASE_TARS}" + openim::release::package_src_tarball & + openim::release::package_client_tarballs & + openim::release::package_iam_manifests_tarball & + openim::release::package_server_tarballs & + openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; } + + openim::release::package_final_tarball & # _final depends on some of the previous phases + openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; } +} + +function openim::release::updload_tarballs() { + openim::log::info "upload ${RELEASE_TARS}/* to cos bucket ${BUCKET}." + for file in $(ls ${RELEASE_TARS}/*) + do + if [ "${COSTOOL}" == "coscli" ];then + coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/${file##*/}" + coscli cp "${file}" "cos://${BUCKET}/${COS_RELEASE_DIR}/latest/${file##*/}" + else + coscmd upload "${file}" "${COS_RELEASE_DIR}/${OPENIM_GIT_VERSION}/" + coscmd upload "${file}" "${COS_RELEASE_DIR}/latest/" + fi + done +} + +# Package the source code we built, for compliance/licensing/audit/yadda. +function openim::release::package_src_tarball() { + local -r src_tarball="${RELEASE_TARS}/openim-src.tar.gz" + openim::log::status "Building tarball: src" + if [[ "${OPENIM_GIT_TREE_STATE-}" = 'clean' ]]; then + git archive -o "${src_tarball}" HEAD + else + find "${OPENIM_ROOT}" -mindepth 1 -maxdepth 1 \ + ! \( \ + \( -path "${OPENIM_ROOT}"/_\* -o \ + -path "${OPENIM_ROOT}"/.git\* -o \ + -path "${OPENIM_ROOT}"/.github\* -o \ + -path "${OPENIM_ROOT}"/.gitignore\* -o \ + -path "${OPENIM_ROOT}"/.gsemver.yml\* -o \ + -path "${OPENIM_ROOT}"/.config\* -o \ + -path "${OPENIM_ROOT}"/.chglog\* -o \ + -path "${OPENIM_ROOT}"/.gitlint -o \ + -path "${OPENIM_ROOT}"/.golangci.yml -o \ + -path "${OPENIM_ROOT}"/.goreleaser.yml -o \ + -path "${OPENIM_ROOT}"/.note.md -o \ + -path "${OPENIM_ROOT}"/.todo.md \ + \) -prune \ + \) -print0 \ + | "${TAR}" czf "${src_tarball}" --transform "s|${OPENIM_ROOT#/*}|openim|" --null -T - + fi +} + +# Package up all of the server binaries +function openim::release::package_server_tarballs() { + # Find all of the built client binaries + local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*) + if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then + read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}" + fi + + for platform_long in "${long_platforms[@]}"; do + local platform + local platform_tag + platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH + platform_tag=${platform/\//-} # Replace a "/" for a "-" + openim::log::status "Starting tarball: server $platform_tag" + + ( + local release_stage="${RELEASE_STAGE}/server/${platform_tag}/openim" + rm -rf "${release_stage}" + mkdir -p "${release_stage}/server/bin" + + local server_bins=("${OPENIM_SERVER_BINARIES[@]}") + + # This fancy expression will expand to prepend a path + # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the + # server_bins array. + cp "${server_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ + "${release_stage}/server/bin/" + + openim::release::clean_cruft + + local package_name="${RELEASE_TARS}/openim-server-${platform_tag}.tar.gz" + openim::release::create_tarball "${package_name}" "${release_stage}/.." + ) & + done + + openim::log::status "Waiting on tarballs" + openim::util::wait-for-jobs || { openim::log::error "server tarball creation failed"; exit 1; } + } + +# Package up all of the cross compiled clients. Over time this should grow into +# a full SDK +function openim::release::package_client_tarballs() { + # Find all of the built client binaries + local long_platforms=("${LOCAL_OUTPUT_BINPATH}"/*/*) + if [[ -n ${OPENIM_BUILD_PLATFORMS-} ]]; then + read -ra long_platforms <<< "${OPENIM_BUILD_PLATFORMS}" + fi + + for platform_long in "${long_platforms[@]}"; do + local platform + local platform_tag + platform=${platform_long##${LOCAL_OUTPUT_BINPATH}/} # Strip LOCAL_OUTPUT_BINPATH + platform_tag=${platform/\//-} # Replace a "/" for a "-" + openim::log::status "Starting tarball: client $platform_tag" + + ( + local release_stage="${RELEASE_STAGE}/client/${platform_tag}/openim" + rm -rf "${release_stage}" + mkdir -p "${release_stage}/client/bin" + + local client_bins=("${OPENIM_CLIENT_BINARIES[@]}") + + # This fancy expression will expand to prepend a path + # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the + # client_bins array. + cp "${client_bins[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ + "${release_stage}/client/bin/" + + openim::release::clean_cruft + + local package_name="${RELEASE_TARS}/openim-client-${platform_tag}.tar.gz" + openim::release::create_tarball "${package_name}" "${release_stage}/.." + ) & + done + + openim::log::status "Waiting on tarballs" + openim::util::wait-for-jobs || { openim::log::error "client tarball creation failed"; exit 1; } +} + +# Package up all of the server binaries in docker images +function openim::release::build_server_images() { + # Clean out any old images + rm -rf "${RELEASE_IMAGES}" + local platform + for platform in "${OPENIM_SERVER_PLATFORMS[@]}"; do + local platform_tag + local arch + platform_tag=${platform/\//-} # Replace a "/" for a "-" + arch=$(basename "${platform}") + openim::log::status "Building images: $platform_tag" + + local release_stage + release_stage="${RELEASE_STAGE}/server/${platform_tag}/openim" + rm -rf "${release_stage}" + mkdir -p "${release_stage}/server/bin" + + # This fancy expression will expand to prepend a path + # (${LOCAL_OUTPUT_BINPATH}/${platform}/) to every item in the + # OPENIM_SERVER_IMAGE_BINARIES array. + cp "${OPENIM_SERVER_IMAGE_BINARIES[@]/#/${LOCAL_OUTPUT_BINPATH}/${platform}/}" \ + "${release_stage}/server/bin/" + + openim::release::create_docker_images_for_server "${release_stage}/server/bin" "${arch}" + done +} + +function openim::release::md5() { + if which md5 >/dev/null 2>&1; then + md5 -q "$1" + else + md5sum "$1" | awk '{ print $1 }' + fi +} + +function openim::release::sha1() { + if which sha1sum >/dev/null 2>&1; then + sha1sum "$1" | awk '{ print $1 }' + else + shasum -a1 "$1" | awk '{ print $1 }' + fi +} + +function openim::release::sha256() { + if which sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{ print $1 }' + else + shasum -a256 "$1" | awk '{ print $1 }' + fi +} + +function openim::release::build_conformance_image() { + local -r arch="$1" + local -r registry="$2" + local -r version="$3" + local -r save_dir="${4-}" + openim::log::status "Building conformance image for arch: ${arch}" + ARCH="${arch}" REGISTRY="${registry}" VERSION="${version}" \ + make -C cluster/images/conformance/ build >/dev/null + + local conformance_tag + conformance_tag="${registry}/conformance-${arch}:${version}" + if [[ -n "${save_dir}" ]]; then + "${DOCKER[@]}" save "${conformance_tag}" > "${save_dir}/conformance-${arch}.tar" + fi + openim::log::status "Deleting conformance image ${conformance_tag}" + "${DOCKER[@]}" rmi "${conformance_tag}" &>/dev/null || true +} + +# This builds all the release docker images (One docker image per binary) +# Args: +# $1 - binary_dir, the directory to save the tared images to. +# $2 - arch, architecture for which we are building docker images. +function openim::release::create_docker_images_for_server() { + # Create a sub-shell so that we don't pollute the outer environment + ( + local binary_dir + local arch + local binaries + local images_dir + binary_dir="$1" + arch="$2" + binaries=$(openim::build::get_docker_wrapped_binaries "${arch}") + images_dir="${RELEASE_IMAGES}/${arch}" + mkdir -p "${images_dir}" + + # k8s.gcr.io is the constant tag in the docker archives, this is also the default for config scripts in GKE. + # We can use OPENIM_DOCKER_REGISTRY to include and extra registry in the docker archive. + # If we use OPENIM_DOCKER_REGISTRY="k8s.gcr.io", then the extra tag (same) is ignored, see release_docker_image_tag below. + local -r docker_registry="k8s.gcr.io" + # Docker tags cannot contain '+' + local docker_tag="${OPENIM_GIT_VERSION/+/_}" + if [[ -z "${docker_tag}" ]]; then + openim::log::error "git version information missing; cannot create Docker tag" + return 1 + fi + + # provide `--pull` argument to `docker build` if `OPENIM_BUILD_PULL_LATEST_IMAGES` + # is set to y or Y; otherwise try to build the image without forcefully + # pulling the latest base image. + local docker_build_opts + docker_build_opts= + if [[ "${OPENIM_BUILD_PULL_LATEST_IMAGES}" =~ [yY] ]]; then + docker_build_opts='--pull' + fi + + for wrappable in $binaries; do + + local binary_name=${wrappable%%,*} + local base_image=${wrappable##*,} + local binary_file_path="${binary_dir}/${binary_name}" + local docker_build_path="${binary_file_path}.dockerbuild" + local docker_file_path="${docker_build_path}/Dockerfile" + local docker_image_tag="${docker_registry}/${binary_name}-${arch}:${docker_tag}" + + openim::log::status "Starting docker build for image: ${binary_name}-${arch}" + ( + rm -rf "${docker_build_path}" + mkdir -p "${docker_build_path}" + ln "${binary_file_path}" "${docker_build_path}/${binary_name}" + ln "${OPENIM_ROOT}/build/nsswitch.conf" "${docker_build_path}/nsswitch.conf" + chmod 0644 "${docker_build_path}/nsswitch.conf" + cat < "${docker_file_path}" +FROM ${base_image} +COPY ${binary_name} /usr/local/bin/${binary_name} +EOF + # ensure /etc/nsswitch.conf exists so go's resolver respects /etc/hosts + if [[ "${base_image}" =~ busybox ]]; then + echo "COPY nsswitch.conf /etc/" >> "${docker_file_path}" + fi + + "${DOCKER[@]}" build ${docker_build_opts:+"${docker_build_opts}"} -q -t "${docker_image_tag}" "${docker_build_path}" >/dev/null + # If we are building an official/alpha/beta release we want to keep + # docker images and tag them appropriately. + local -r release_docker_image_tag="${OPENIM_DOCKER_REGISTRY-$docker_registry}/${binary_name}-${arch}:${OPENIM_DOCKER_IMAGE_TAG-$docker_tag}" + if [[ "${release_docker_image_tag}" != "${docker_image_tag}" ]]; then + openim::log::status "Tagging docker image ${docker_image_tag} as ${release_docker_image_tag}" + "${DOCKER[@]}" rmi "${release_docker_image_tag}" 2>/dev/null || true + "${DOCKER[@]}" tag "${docker_image_tag}" "${release_docker_image_tag}" 2>/dev/null + fi + "${DOCKER[@]}" save -o "${binary_file_path}.tar" "${docker_image_tag}" "${release_docker_image_tag}" + echo "${docker_tag}" > "${binary_file_path}.docker_tag" + rm -rf "${docker_build_path}" + ln "${binary_file_path}.tar" "${images_dir}/" + + openim::log::status "Deleting docker image ${docker_image_tag}" + "${DOCKER[@]}" rmi "${docker_image_tag}" &>/dev/null || true + ) & + done + + if [[ "${OPENIM_BUILD_CONFORMANCE}" =~ [yY] ]]; then + openim::release::build_conformance_image "${arch}" "${docker_registry}" \ + "${docker_tag}" "${images_dir}" & + fi + + openim::util::wait-for-jobs || { openim::log::error "previous Docker build failed"; return 1; } + openim::log::status "Docker builds done" + ) + +} + +# This will pack openim-system manifests files for distros such as COS. +function openim::release::package_iam_manifests_tarball() { + openim::log::status "Building tarball: manifests" + + local src_dir="${OPENIM_ROOT}/deployments" + + local release_stage="${RELEASE_STAGE}/manifests/openim" + rm -rf "${release_stage}" + + local dst_dir="${release_stage}" + mkdir -p "${dst_dir}" + cp -r ${src_dir}/* "${dst_dir}" + #cp "${src_dir}/openim-apiserver.yaml" "${dst_dir}" + #cp "${src_dir}/openim-authz-server.yaml" "${dst_dir}" + #cp "${src_dir}/openim-pump.yaml" "${dst_dir}" + #cp "${src_dir}/openim-watcher.yaml" "${dst_dir}" + #cp "${OPENIM_ROOT}/cluster/gce/gci/health-monitor.sh" "${dst_dir}/health-monitor.sh" + + openim::release::clean_cruft + + local package_name="${RELEASE_TARS}/openim-manifests.tar.gz" + openim::release::create_tarball "${package_name}" "${release_stage}/.." +} + +# This is all the platform-independent stuff you need to run/install openim. +# Arch-specific binaries will need to be downloaded separately (possibly by +# using the bundled cluster/get-openim-binaries.sh script). +# Included in this tarball: +# - Cluster spin up/down scripts and configs for various cloud providers +# - Tarballs for manifest configs that are ready to be uploaded +# - Examples (which may or may not still work) +# - The remnants of the docs/ directory +function openim::release::package_final_tarball() { + openim::log::status "Building tarball: final" + + # This isn't a "full" tarball anymore, but the release lib still expects + # artifacts under "full/openim/" + local release_stage="${RELEASE_STAGE}/full/openim" + rm -rf "${release_stage}" + mkdir -p "${release_stage}" + + mkdir -p "${release_stage}/client" + cat < "${release_stage}/client/README" +Client binaries are no longer included in the OpenIM final tarball. + +Run release/get-openim-binaries.sh to download client and server binaries. +EOF + + # We want everything in /scripts. + mkdir -p "${release_stage}/release" + cp -R "${OPENIM_ROOT}/scripts/release" "${release_stage}/" + cat < "${release_stage}/release/get-openim-binaries.sh" +#!/usr/bin/env bash + +# Copyright 2020 Lingfei Kong . All rights reserved. +# Use of this source code is governed by a MIT style +# license that can be found in the LICENSE file. + +# This file download openim client and server binaries from tencent cos bucket. + +os=linux arch=amd64 version=${OPENIM_GIT_VERSION} && wget https://${BUCKET}.cos.${REGION}.myqcloud.com/${COS_RELEASE_DIR}/\$version/{openim-client-\$os-\$arch.tar.gz,openim-server-\$os-\$arch.tar.gz} +EOF + chmod +x ${release_stage}/release/get-openim-binaries.sh + + mkdir -p "${release_stage}/server" + cp "${RELEASE_TARS}/openim-manifests.tar.gz" "${release_stage}/server/" + cat < "${release_stage}/server/README" +Server binary tarballs are no longer included in the OpenIM final tarball. + +Run release/get-openim-binaries.sh to download client and server binaries. +EOF + + # Include hack/lib as a dependency for the cluster/ scripts + #mkdir -p "${release_stage}/hack" + #cp -R "${OPENIM_ROOT}/hack/lib" "${release_stage}/hack/" + + cp -R ${OPENIM_ROOT}/{docs,configs,scripts,deployments,init,README.md,LICENSE} "${release_stage}/" + + echo "${OPENIM_GIT_VERSION}" > "${release_stage}/version" + + openim::release::clean_cruft + + local package_name="${RELEASE_TARS}/${ARTIFACT}" + openim::release::create_tarball "${package_name}" "${release_stage}/.." +} + +# Build a release tarball. $1 is the output tar name. $2 is the base directory +# of the files to be packaged. This assumes that ${2}/iamis what is +# being packaged. +function openim::release::create_tarball() { + openim::build::ensure_tar + + local tarfile=$1 + local stagingdir=$2 + + "${TAR}" czf "${tarfile}" -C "${stagingdir}" openim --owner=0 --group=0 +} + +function openim::release::install_github_release(){ + GO111MODULE=on go install github.com/github-release/github-release@latest +} + +# Require the following tools: +# - github-release +# - gsemver +# - git-chglog +# - coscmd or coscli +function openim::release::verify_prereqs(){ + if [ -z "$(which github-release 2>/dev/null)" ]; then + openim::log::info "'github-release' tool not installed, try to install it." + + if ! openim::release::install_github_release; then + openim::log::error "failed to install 'github-release'" + return 1 + fi + fi + + if [ -z "$(which git-chglog 2>/dev/null)" ]; then + openim::log::info "'git-chglog' tool not installed, try to install it." + + if ! go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest &>/dev/null; then + openim::log::error "failed to install 'git-chglog'" + return 1 + fi + fi + + if [ -z "$(which gsemver 2>/dev/null)" ]; then + openim::log::info "'gsemver' tool not installed, try to install it." + + if ! go install github.com/arnaud-deprez/gsemver@latest &>/dev/null; then + openim::log::error "failed to install 'gsemver'" + return 1 + fi + fi + + + if [ -z "$(which ${COSTOOL} 2>/dev/null)" ]; then + openim::log::info "${COSTOOL} tool not installed, try to install it." + + if ! make -C "${OPENIM_ROOT}" tools.install.${COSTOOL}; then + openim::log::error "failed to install ${COSTOOL}" + return 1 + fi + fi + + if [ -z "${TENCENT_SECRET_ID}" -o -z "${TENCENT_SECRET_KEY}" ];then + openim::log::error "can not find env: TENCENT_SECRET_ID and TENCENT_SECRET_KEY" + return 1 + fi + + if [ "${COSTOOL}" == "coscli" ];then + if [ ! -f "${HOME}/.cos.yaml" ];then + cat << EOF > "${HOME}/.cos.yaml" +cos: + base: + secretid: ${TENCENT_SECRET_ID} + secretkey: ${TENCENT_SECRET_KEY} + sessiontoken: "" + buckets: + - name: ${BUCKET} + alias: ${BUCKET} + region: ${REGION} +EOF + fi + else + if [ ! -f "${HOME}/.cos.conf" ];then + cat << EOF > "${HOME}/.cos.conf" +[common] +secret_id = ${TENCENT_SECRET_ID} +secret_key = ${TENCENT_SECRET_KEY} +bucket = ${BUCKET} +region =${REGION} +max_thread = 5 +part_size = 1 +schema = https +EOF + fi + fi +} + +# Create a github release with specified tarballs. +# NOTICE: Must export 'GITHUB_TOKEN' env in the shell, details: +# https://github.com/github-release/github-release +function openim::release::github_release() { + # create a github release + openim::log::info "create a new github release with tag ${OPENIM_GIT_VERSION}" + github-release release \ + --user ${OPENIM_GITHUB_ORG} \ + --repo ${OPENIM_GITHUB_REPO} \ + --tag ${OPENIM_GIT_VERSION} \ + --description "" \ + --pre-release + + # update openim tarballs + openim::log::info "upload ${ARTIFACT} to release ${OPENIM_GIT_VERSION}" + github-release upload \ + --user ${OPENIM_GITHUB_ORG} \ + --repo ${OPENIM_GITHUB_REPO} \ + --tag ${OPENIM_GIT_VERSION} \ + --name ${ARTIFACT} \ + --file ${RELEASE_TARS}/${ARTIFACT} + + openim::log::info "upload openim-src.tar.gz to release ${OPENIM_GIT_VERSION}" + github-release upload \ + --user ${OPENIM_GITHUB_ORG} \ + --repo ${OPENIM_GITHUB_REPO} \ + --tag ${OPENIM_GIT_VERSION} \ + --name "openim-src.tar.gz" \ + --file ${RELEASE_TARS}/openim-src.tar.gz +} + +function openim::release::generate_changelog() { + openim::log::info "generate CHANGELOG-${OPENIM_GIT_VERSION#v}.md and commit it" + + git-chglog ${OPENIM_GIT_VERSION} > ${OPENIM_ROOT}/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md + + set +o errexit + git add ${OPENIM_ROOT}/CHANGELOG/CHANGELOG-${OPENIM_GIT_VERSION#v}.md + git commit -a -m "docs(changelog): add CHANGELOG-${OPENIM_GIT_VERSION#v}.md" + git push -f origin master # ζœ€εŽε°† CHANGELOG 也 push 上去 +} diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh new file mode 100755 index 0000000..2f32dac --- /dev/null +++ b/scripts/lib/util.sh @@ -0,0 +1,693 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +function openim::util::sourced_variable { + # Call this function to tell shellcheck that a variable is supposed to + # be used from other calling context. This helps quiet an "unused + # variable" warning from shellcheck and also document your code. + true +} + +openim::util::sortable_date() { + date "+%Y%m%d-%H%M%S" +} + +# arguments: target, item1, item2, item3, ... +# returns 0 if target is in the given items, 1 otherwise. +openim::util::array_contains() { + local search="$1" + local element + shift + for element; do + if [[ "${element}" == "${search}" ]]; then + return 0 + fi + done + return 1 +} + +openim::util::wait_for_url() { + local url=$1 + local prefix=${2:-} + local wait=${3:-1} + local times=${4:-30} + local maxtime=${5:-1} + + command -v curl >/dev/null || { + openim::log::usage "curl must be installed" + exit 1 + } + + local i + for i in $(seq 1 "${times}"); do + local out + if out=$(curl --max-time "${maxtime}" -gkfs "${url}" 2>/dev/null); then + openim::log::status "On try ${i}, ${prefix}: ${out}" + return 0 + fi + sleep "${wait}" + done + openim::log::error "Timed out waiting for ${prefix} to answer at ${url}; tried ${times} waiting ${wait} between each" + return 1 +} + +# Example: openim::util::wait_for_success 120 5 "iamctl get nodes|grep localhost" +# arguments: wait time, sleep time, shell command +# returns 0 if the shell command get output, 1 otherwise. +openim::util::wait_for_success(){ + local wait_time="$1" + local sleep_time="$2" + local cmd="$3" + while [ "$wait_time" -gt 0 ]; do + if eval "$cmd"; then + return 0 + else + sleep "$sleep_time" + wait_time=$((wait_time-sleep_time)) + fi + done + return 1 +} + +# Example: openim::util::trap_add 'echo "in trap DEBUG"' DEBUG +# See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal +openim::util::trap_add() { + local trap_add_cmd + trap_add_cmd=$1 + shift + + for trap_add_name in "$@"; do + local existing_cmd + local new_cmd + + # Grab the currently defined trap commands for this trap + existing_cmd=$(trap -p "${trap_add_name}" | awk -F"'" '{print $2}') + + if [[ -z "${existing_cmd}" ]]; then + new_cmd="${trap_add_cmd}" + else + new_cmd="${trap_add_cmd};${existing_cmd}" + fi + + # Assign the test. Disable the shellcheck warning telling that trap + # commands should be single quoted to avoid evaluating them at this + # point instead evaluating them at run time. The logic of adding new + # commands to a single trap requires them to be evaluated right away. + # shellcheck disable=SC2064 + trap "${new_cmd}" "${trap_add_name}" + done +} + +# Opposite of openim::util::ensure-temp-dir() +openim::util::cleanup-temp-dir() { + rm -rf "${OPENIM_TEMP}" +} + +# Create a temp dir that'll be deleted at the end of this bash session. +# +# Vars set: +# OPENIM_TEMP +openim::util::ensure-temp-dir() { + if [[ -z ${OPENIM_TEMP-} ]]; then + OPENIM_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t iamrnetes.XXXXXX) + openim::util::trap_add openim::util::cleanup-temp-dir EXIT + fi +} + +openim::util::host_os() { + local host_os + case "$(uname -s)" in + Darwin) + host_os=darwin + ;; + Linux) + host_os=linux + ;; + *) + openim::log::error "Unsupported host OS. Must be Linux or Mac OS X." + exit 1 + ;; + esac + echo "${host_os}" +} + +openim::util::host_arch() { + local host_arch + case "$(uname -m)" in + x86_64*) + host_arch=amd64 + ;; + i?86_64*) + host_arch=amd64 + ;; + amd64*) + host_arch=amd64 + ;; + aarch64*) + host_arch=arm64 + ;; + arm64*) + host_arch=arm64 + ;; + arm*) + host_arch=arm + ;; + i?86*) + host_arch=x86 + ;; + s390x*) + host_arch=s390x + ;; + ppc64le*) + host_arch=ppc64le + ;; + *) + openim::log::error "Unsupported host arch. Must be x86_64, 386, arm, arm64, s390x or ppc64le." + exit 1 + ;; + esac + echo "${host_arch}" +} + +# This figures out the host platform without relying on golang. We need this as +# we don't want a golang install to be a prerequisite to building yet we need +# this info to figure out where the final binaries are placed. +openim::util::host_platform() { + echo "$(openim::util::host_os)/$(openim::util::host_arch)" +} + +# looks for $1 in well-known output locations for the platform ($2) +# $OPENIM_ROOT must be set +openim::util::find-binary-for-platform() { + local -r lookfor="$1" + local -r platform="$2" + local locations=( + "${OPENIM_ROOT}/_output/bin/${lookfor}" + "${OPENIM_ROOT}/_output/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/local/bin/${platform}/${lookfor}" + "${OPENIM_ROOT}/_output/platforms/${platform}/${lookfor}" + ) + + # List most recently-updated location. + local -r bin=$( (ls -t "${locations[@]}" 2>/dev/null || true) | head -1 ) + echo -n "${bin}" +} + +# looks for $1 in well-known output locations for the host platform +# $OPENIM_ROOT must be set +openim::util::find-binary() { + openim::util::find-binary-for-platform "$1" "$(openim::util::host_platform)" +} + +# Run all known doc generators (today gendocs and genman for iamctl) +# $1 is the directory to put those generated documents +openim::util::gen-docs() { + local dest="$1" + + # Find binary + gendocs=$(openim::util::find-binary "gendocs") + geniamdocs=$(openim::util::find-binary "geniamdocs") + genman=$(openim::util::find-binary "genman") + genyaml=$(openim::util::find-binary "genyaml") + genfeddocs=$(openim::util::find-binary "genfeddocs") + + # TODO: If ${genfeddocs} is not used from anywhere (it isn't used at + # least from k/k tree), remove it completely. + openim::util::sourced_variable "${genfeddocs}" + + mkdir -p "${dest}/docs/guide/en-US/cmd/iamctl/" + "${gendocs}" "${dest}/docs/guide/en-US/cmd/iamctl/" + + mkdir -p "${dest}/docs/guide/en-US/cmd/" + "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-apiserver" + "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-authz-server" + "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-pump" + "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-watcher" + "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/iamctl" "iamctl" + + mkdir -p "${dest}/docs/man/man1/" + "${genman}" "${dest}/docs/man/man1/" "openim-apiserver" + "${genman}" "${dest}/docs/man/man1/" "openim-authz-server" + "${genman}" "${dest}/docs/man/man1/" "openim-pump" + "${genman}" "${dest}/docs/man/man1/" "openim-watcher" + "${genman}" "${dest}/docs/man/man1/" "iamctl" + + mkdir -p "${dest}/docs/guide/en-US/yaml/iamctl/" + "${genyaml}" "${dest}/docs/guide/en-US/yaml/iamctl/" + + # create the list of generated files + pushd "${dest}" > /dev/null || return 1 + touch docs/.generated_docs + find . -type f | cut -sd / -f 2- | LC_ALL=C sort > docs/.generated_docs + popd > /dev/null || return 1 +} + +# Removes previously generated docs-- we don't want to check them in. $OPENIM_ROOT +# must be set. +openim::util::remove-gen-docs() { + if [ -e "${OPENIM_ROOT}/docs/.generated_docs" ]; then + # remove all of the old docs; we don't want to check them in. + while read -r file; do + rm "${OPENIM_ROOT}/${file}" 2>/dev/null || true + done <"${OPENIM_ROOT}/docs/.generated_docs" + # The docs/.generated_docs file lists itself, so we don't need to explicitly + # delete it. + fi +} + +# Returns the name of the upstream remote repository name for the local git +# repo, e.g. "upstream" or "origin". +openim::util::git_upstream_remote_name() { + git remote -v | grep fetch |\ + grep -E 'github.com[/:]marmotedu/openim|marmotedu.io/openim' |\ + head -n 1 | awk '{print $1}' +} + +# Exits script if working directory is dirty. If it's run interactively in the terminal +# the user can commit changes in a second terminal. This script will wait. +openim::util::ensure_clean_working_dir() { + while ! git diff HEAD --exit-code &>/dev/null; do + echo -e "\nUnexpected dirty working directory:\n" + if tty -s; then + git status -s + else + git diff -a # be more verbose in log files without tty + exit 1 + fi | sed 's/^/ /' + echo -e "\nCommit your changes in another terminal and then continue here by pressing enter." + read -r + done 1>&2 +} + +# Find the base commit using: +# $PULL_BASE_SHA if set (from Prow) +# current ref from the remote upstream branch +openim::util::base_ref() { + local -r git_branch=$1 + + if [[ -n ${PULL_BASE_SHA:-} ]]; then + echo "${PULL_BASE_SHA}" + return + fi + + full_branch="$(openim::util::git_upstream_remote_name)/${git_branch}" + + # make sure the branch is valid, otherwise the check will pass erroneously. + if ! git describe "${full_branch}" >/dev/null; then + # abort! + exit 1 + fi + + echo "${full_branch}" +} + +# Checks whether there are any files matching pattern $2 changed between the +# current branch and upstream branch named by $1. +# Returns 1 (false) if there are no changes +# 0 (true) if there are changes detected. +openim::util::has_changes() { + local -r git_branch=$1 + local -r pattern=$2 + local -r not_pattern=${3:-totallyimpossiblepattern} + + local base_ref + base_ref=$(openim::util::base_ref "${git_branch}") + echo "Checking for '${pattern}' changes against '${base_ref}'" + + # notice this uses ... to find the first shared ancestor + if git diff --name-only "${base_ref}...HEAD" | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then + return 0 + fi + # also check for pending changes + if git status --porcelain | grep -v -E "${not_pattern}" | grep "${pattern}" > /dev/null; then + echo "Detected '${pattern}' uncommitted changes." + return 0 + fi + echo "No '${pattern}' changes detected." + return 1 +} + +openim::util::download_file() { + local -r url=$1 + local -r destination_file=$2 + + rm "${destination_file}" 2&> /dev/null || true + + for i in $(seq 5) + do + if ! curl -fsSL --retry 3 --keepalive-time 2 "${url}" -o "${destination_file}"; then + echo "Downloading ${url} failed. $((5-i)) retries left." + sleep 1 + else + echo "Downloading ${url} succeed" + return 0 + fi + done + return 1 +} + +# Test whether openssl is installed. +# Sets: +# OPENSSL_BIN: The path to the openssl binary to use +function openim::util::test_openssl_installed { + if ! openssl version >& /dev/null; then + echo "Failed to run openssl. Please ensure openssl is installed" + exit 1 + fi + + OPENSSL_BIN=$(command -v openssl) +} + +# creates a client CA, args are sudo, dest-dir, ca-id, purpose +# purpose is dropped in after "key encipherment", you usually want +# '"client auth"' +# '"server auth"' +# '"client auth","server auth"' +function openim::util::create_signing_certkey { + local sudo=$1 + local dest_dir=$2 + local id=$3 + local purpose=$4 + # Create client ca + ${sudo} /usr/bin/env bash -e < "${dest_dir}/${id}-ca-config.json" +EOF +} + +# signs a client certificate: args are sudo, dest-dir, CA, filename (roughly), username, groups... +function openim::util::create_client_certkey { + local sudo=$1 + local dest_dir=$2 + local ca=$3 + local id=$4 + local cn=${5:-$4} + local groups="" + local SEP="" + shift 5 + while [ -n "${1:-}" ]; do + groups+="${SEP}{\"O\":\"$1\"}" + SEP="," + shift 1 + done + ${sudo} /usr/bin/env bash -e < /dev/null +apiVersion: v1 +kind: Config +clusters: + - cluster: + certificate-authority: ${ca_file} + server: https://${api_host}:${api_port}/ + name: local-up-cluster +users: + - user: + token: ${token} + client-certificate: ${dest_dir}/client-${client_id}.crt + client-key: ${dest_dir}/client-${client_id}.key + name: local-up-cluster +contexts: + - context: + cluster: local-up-cluster + user: local-up-cluster + name: local-up-cluster +current-context: local-up-cluster +EOF + + # flatten the iamconfig files to make them self contained + username=$(whoami) + ${sudo} /usr/bin/env bash -e < "/tmp/${client_id}.iamconfig" + mv -f "/tmp/${client_id}.iamconfig" "${dest_dir}/${client_id}.iamconfig" + chown ${username} "${dest_dir}/${client_id}.iamconfig" +EOF +} + +# Determines if docker can be run, failures may simply require that the user be added to the docker group. +function openim::util::ensure_docker_daemon_connectivity { + IFS=" " read -ra DOCKER <<< "${DOCKER_OPTS}" + # Expand ${DOCKER[@]} only if it's not unset. This is to work around + # Bash 3 issue with unbound variable. + DOCKER=(docker ${DOCKER[@]:+"${DOCKER[@]}"}) + if ! "${DOCKER[@]}" info > /dev/null 2>&1 ; then + cat <<'EOF' >&2 +Can't connect to 'docker' daemon. please fix and retry. + +Possible causes: + - Docker Daemon not started + - Linux: confirm via your init system + - macOS w/ docker-machine: run `docker-machine ls` and `docker-machine start ` + - macOS w/ Docker for Mac: Check the menu bar and start the Docker application + - DOCKER_HOST hasn't been set or is set incorrectly + - Linux: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}` + - macOS w/ docker-machine: run `eval "$(docker-machine env )"` + - macOS w/ Docker for Mac: domain socket is used, DOCKER_* should be unset. In Bash run `unset ${!DOCKER_*}` + - Other things to check: + - Linux: User isn't in 'docker' group. Add and relogin. + - Something like 'sudo usermod -a -G docker ${USER}' + - RHEL7 bug and workaround: https://bugzilla.redhat.com/show_bug.cgi?id=1119282#c8 +EOF + return 1 + fi +} + +# Wait for background jobs to finish. Return with +# an error status if any of the jobs failed. +openim::util::wait-for-jobs() { + local fail=0 + local job + for job in $(jobs -p); do + wait "${job}" || fail=$((fail + 1)) + done + return ${fail} +} + +# openim::util::join +# Concatenates the list elements with the delimiter passed as first parameter +# +# Ex: openim::util::join , a b c +# -> a,b,c +function openim::util::join { + local IFS="$1" + shift + echo "$*" +} + +# Downloads cfssl/cfssljson/cfssl-certinfo into $1 directory if they do not already exist in PATH +# +# Assumed vars: +# $1 (cfssl directory) (optional) +# +# Sets: +# CFSSL_BIN: The path of the installed cfssl binary +# CFSSLJSON_BIN: The path of the installed cfssljson binary +# CFSSLCERTINFO_BIN: The path of the installed cfssl-certinfo binary +# +function openim::util::ensure-cfssl { + if command -v cfssl &>/dev/null && command -v cfssljson &>/dev/null && command -v cfssl-certinfo &>/dev/null; then + CFSSL_BIN=$(command -v cfssl) + CFSSLJSON_BIN=$(command -v cfssljson) + CFSSLCERTINFO_BIN=$(command -v cfssl-certinfo) + return 0 + fi + + host_arch=$(openim::util::host_arch) + + if [[ "${host_arch}" != "amd64" ]]; then + echo "Cannot download cfssl on non-amd64 hosts and cfssl does not appear to be installed." + echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH." + echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..." + exit 1 + fi + + # Create a temp dir for cfssl if no directory was given + local cfssldir=${1:-} + if [[ -z "${cfssldir}" ]]; then + cfssldir="$HOME/bin" + fi + + mkdir -p "${cfssldir}" + pushd "${cfssldir}" > /dev/null || return 1 + + echo "Unable to successfully run 'cfssl' from ${PATH}; downloading instead..." + kernel=$(uname -s) + case "${kernel}" in + Linux) + curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 + curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 + curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 + ;; + Darwin) + curl --retry 10 -L -o cfssl https://pkg.cfssl.org/R1.2/cfssl_darwin-amd64 + curl --retry 10 -L -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_darwin-amd64 + curl --retry 10 -L -o cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_darwin-amd64 + ;; + *) + echo "Unknown, unsupported platform: ${kernel}." >&2 + echo "Supported platforms: Linux, Darwin." >&2 + exit 2 + esac + + chmod +x cfssl || true + chmod +x cfssljson || true + chmod +x cfssl-certinfo || true + + CFSSL_BIN="${cfssldir}/cfssl" + CFSSLJSON_BIN="${cfssldir}/cfssljson" + CFSSLCERTINFO_BIN="${cfssldir}/cfssl-certinfo" + if [[ ! -x ${CFSSL_BIN} || ! -x ${CFSSLJSON_BIN} || ! -x ${CFSSLCERTINFO_BIN} ]]; then + echo "Failed to download 'cfssl'." + echo "Please install cfssl, cfssljson and cfssl-certinfo and verify they are in \$PATH." + echo "Hint: export PATH=\$PATH:\$GOPATH/bin; go get -u github.com/cloudflare/cfssl/cmd/..." + exit 1 + fi + popd > /dev/null || return 1 +} + +# openim::util::ensure-gnu-sed +# Determines which sed binary is gnu-sed on linux/darwin +# +# Sets: +# SED: The name of the gnu-sed binary +# +function openim::util::ensure-gnu-sed { + # NOTE: the echo below is a workaround to ensure sed is executed before the grep. + # see: https://github.com/iamrnetes/iamrnetes/issues/87251 + sed_help="$(LANG=C sed --help 2>&1 || true)" + if echo "${sed_help}" | grep -q "GNU\|BusyBox"; then + SED="sed" + elif command -v gsed &>/dev/null; then + SED="gsed" + else + openim::log::error "Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed." >&2 + return 1 + fi + openim::util::sourced_variable "${SED}" +} + +# openim::util::check-file-in-alphabetical-order +# Check that the file is in alphabetical order +# +function openim::util::check-file-in-alphabetical-order { + local failure_file="$1" + if ! diff -u "${failure_file}" <(LC_ALL=C sort "${failure_file}"); then + { + echo + echo "${failure_file} is not in alphabetical order. Please sort it:" + echo + echo " LC_ALL=C sort -o ${failure_file} ${failure_file}" + echo + } >&2 + false + fi +} + +# openim::util::require-jq +# Checks whether jq is installed. +function openim::util::require-jq { + if ! command -v jq &>/dev/null; then + echo "jq not found. Please install." 1>&2 + return 1 + fi +} + +# outputs md5 hash of $1, works on macOS and Linux +function openim::util::md5() { + if which md5 >/dev/null 2>&1; then + md5 -q "$1" + else + md5sum "$1" | awk '{ print $1 }' + fi +} + +# openim::util::read-array +# Reads in stdin and adds it line by line to the array provided. This can be +# used instead of "mapfile -t", and is bash 3 compatible. +# +# Assumed vars: +# $1 (name of array to create/modify) +# +# Example usage: +# openim::util::read-array files < <(ls -1) +# +function openim::util::read-array { + local i=0 + unset -v "$1" + while IFS= read -r "$1[i++]"; do :; done + eval "[[ \${$1[--i]} ]]" || unset "$1[i]" # ensures last element isn't empty +} + +# Some useful colors. +if [[ -z "${color_start-}" ]]; then + declare -r color_start="\033[" + declare -r color_red="${color_start}0;31m" + declare -r color_yellow="${color_start}0;33m" + declare -r color_green="${color_start}0;32m" + declare -r color_blue="${color_start}1;34m" + declare -r color_cyan="${color_start}1;36m" + declare -r color_norm="${color_start}0m" + + openim::util::sourced_variable "${color_start}" + openim::util::sourced_variable "${color_red}" + openim::util::sourced_variable "${color_yellow}" + openim::util::sourced_variable "${color_green}" + openim::util::sourced_variable "${color_blue}" + openim::util::sourced_variable "${color_cyan}" + openim::util::sourced_variable "${color_norm}" +fi + +# ex: ts=2 sw=2 et filetype=sh diff --git a/scripts/lib/version.sh b/scripts/lib/version.sh new file mode 100755 index 0000000..65f9bb3 --- /dev/null +++ b/scripts/lib/version.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# Copyright Β© 2023 OpenIM. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# ----------------------------------------------------------------------------- +# Version management helpers. These functions help to set, save and load the +# following variables: +# +# OPENIM_GIT_COMMIT - The git commit id corresponding to this +# source code. +# OPENIM_GIT_TREE_STATE - "clean" indicates no changes since the git commit id +# "dirty" indicates source code changes after the git commit id +# "archive" indicates the tree was produced by 'git archive' +# OPENIM_GIT_VERSION - "vX.Y" used to indicate the last release version. +# OPENIM_GIT_MAJOR - The major part of the version +# OPENIM_GIT_MINOR - The minor component of the version + +# Grovels through git to set a set of env variables. +# +# If OPENIM_GIT_VERSION_FILE, this function will load from that file instead of +# querying git. +openim::version::get_version_vars() { + if [[ -n ${OPENIM_GIT_VERSION_FILE-} ]]; then + openim::version::load_version_vars "${OPENIM_GIT_VERSION_FILE}" + return + fi + + # If the iamrnetes source was exported through git archive, then + # we likely don't have a git tree, but these magic values may be filled in. + # shellcheck disable=SC2016,SC2050 + # Disabled as we're not expanding these at runtime, but rather expecting + # that another tool may have expanded these and rewritten the source (!) + if [[ '$Format:%%$' == "%" ]]; then + OPENIM_GIT_COMMIT='$Format:%H$' + OPENIM_GIT_TREE_STATE="archive" + # When a 'git archive' is exported, the '$Format:%D$' below will look + # something like 'HEAD -> release-1.8, tag: v1.8.3' where then 'tag: ' + # can be extracted from it. + if [[ '$Format:%D$' =~ tag:\ (v[^ ,]+) ]]; then + OPENIM_GIT_VERSION="${BASH_REMATCH[1]}" + fi + fi + + local git=(git --work-tree "${OPENIM_ROOT}") + + if [[ -n ${OPENIM_GIT_COMMIT-} ]] || OPENIM_GIT_COMMIT=$("${git[@]}" rev-parse "HEAD^{commit}" 2>/dev/null); then + if [[ -z ${OPENIM_GIT_TREE_STATE-} ]]; then + # Check if the tree is dirty. default to dirty + if git_status=$("${git[@]}" status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then + OPENIM_GIT_TREE_STATE="clean" + else + OPENIM_GIT_TREE_STATE="dirty" + fi + fi + + # Use git describe to find the version based on tags. + if [[ -n ${OPENIM_GIT_VERSION-} ]] || OPENIM_GIT_VERSION=$("${git[@]}" describe --tags --always --match='v*' 2>/dev/null); then + # This translates the "git describe" to an actual semver.org + # compatible semantic version that looks something like this: + # v1.1.0-alpha.0.6+84c76d1142ea4d + # + # TODO: We continue calling this "git version" because so many + # downstream consumers are expecting it there. + # + # These regexes are painful enough in sed... + # We don't want to do them in pure shell, so disable SC2001 + # shellcheck disable=SC2001 + DASHES_IN_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/[^-]//g") + if [[ "${DASHES_IN_VERSION}" == "---" ]] ; then + # shellcheck disable=SC2001 + # We have distance to subversion (v1.1.0-subversion-1-gCommitHash) + OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\+\2/") + elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then + # shellcheck disable=SC2001 + # We have distance to base tag (v1.1.0-1-gCommitHash) + OPENIM_GIT_VERSION=$(echo "${OPENIM_GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/+\1/") + fi + if [[ "${OPENIM_GIT_TREE_STATE}" == "dirty" ]]; then + # git describe --dirty only considers changes to existing files, but + # that is problematic since new untracked .go files affect the build, + # so use our idea of "dirty" from git status instead. + # TODO? + #OPENIM_GIT_VERSION+="-dirty" + : + fi + + # Try to match the "git describe" output to a regex to try to extract + # the "major" and "minor" versions and whether this is the exact tagged + # version or whether the tree is between two tagged versions. + if [[ "${OPENIM_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then + OPENIM_GIT_MAJOR=${BASH_REMATCH[1]} + OPENIM_GIT_MINOR=${BASH_REMATCH[2]} + if [[ -n "${BASH_REMATCH[4]}" ]]; then + OPENIM_GIT_MINOR+="+" + fi + fi + + # If OPENIM_GIT_VERSION is not a valid Semantic Version, then refuse to build. + if ! [[ "${OPENIM_GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then + echo "OPENIM_GIT_VERSION should be a valid Semantic Version. Current value: ${OPENIM_GIT_VERSION}" + echo "Please see more details here: https://semver.org" + exit 1 + fi + fi + fi +} + +# Saves the environment flags to $1 +openim::version::save_version_vars() { + local version_file=${1-} + [[ -n ${version_file} ]] || { + echo "!!! Internal error. No file specified in openim::version::save_version_vars" + return 1 + } + + cat <"${version_file}" +OPENIM_GIT_COMMIT='${OPENIM_GIT_COMMIT-}' +OPENIM_GIT_TREE_STATE='${OPENIM_GIT_TREE_STATE-}' +OPENIM_GIT_VERSION='${OPENIM_GIT_VERSION-}' +OPENIM_GIT_MAJOR='${OPENIM_GIT_MAJOR-}' +OPENIM_GIT_MINOR='${OPENIM_GIT_MINOR-}' +EOF +} + +# Loads up the version variables from file $1 +openim::version::load_version_vars() { + local version_file=${1-} + [[ -n ${version_file} ]] || { + echo "!!! Internal error. No file specified in openim::version::load_version_vars" + return 1 + } + + source "${version_file}" +} diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..63982fe --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,44 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Build a OpenIM release. This will build the binaries, create the Docker +# images and other build artifacts. + +set -o errexit # Exit the script if any command returns a non-zero exit status +set -o nounset # Exit the script if any unset variables are encountered +set -o pipefail # Exit the script if any command in a pipeline fails + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/common.sh" # Source the common.sh script +source "${OPENIM_ROOT}/scripts/lib/release.sh" # Source the release.sh script + +OPENIM_RELEASE_RUN_TESTS=${OPENIM_RELEASE_RUN_TESTS-y} # Set the OPENIM_RELEASE_RUN_TESTS variable + +openim::golang::setup_env # Set up the Golang environment +openim::build::verify_prereqs # Verify prerequisites for building +openim::release::verify_prereqs # Verify prerequisites for releasing + +# Build the image +#openim::build::build_image + +openim::build::build_command # Build the command +openim::release::package_tarballs # Package the tarballs +openim::release::updload_tarballs # Upload the tarballs +git push origin ${VERSION} # Push the code to the remote repository with the specified VERSION + +# GitHub release (commented out) +#openim::release::github_release + +# Generate changelog (commented out) +#openim::release::generate_changelog diff --git a/scripts/template/LICENSE b/scripts/template/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/scripts/template/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/scripts/template/LICENSE_TEMPLATES b/scripts/template/LICENSE_TEMPLATES new file mode 100644 index 0000000..dbc5ce2 --- /dev/null +++ b/scripts/template/LICENSE_TEMPLATES @@ -0,0 +1,13 @@ +Copyright Β© {{.Year}} {{.Holder}} All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/scripts/template/boilerplate.txt b/scripts/template/boilerplate.txt new file mode 100644 index 0000000..2f12334 --- /dev/null +++ b/scripts/template/boilerplate.txt @@ -0,0 +1,3 @@ +Copyright Β© {{.Year}} {{.Holder}} All rights reserved. +Use of this source code is governed by a MIT style +license that can be found in the LICENSE file. diff --git a/scripts/template/footer.md.tmpl b/scripts/template/footer.md.tmpl new file mode 100644 index 0000000..0b563bf --- /dev/null +++ b/scripts/template/footer.md.tmpl @@ -0,0 +1,19 @@ +**Full Changelog**: https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }} + +## Get Involved with interview! + +Your patronage towards interview is greatly appreciated πŸŽ‰πŸŽ‰. + +If you encounter any problems during its usage, please create an issue in the [GitHub repository](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/), we're committed to resolving your problem as soon as possible. + +**Here are some ways to get involved with the interview community:** + +πŸ“’ **Slack Channel**: Join our Slack channels for discussions, communication, and support. Click [here](https://join.slack.com/t/aicworld/shared_invite/zt-22720d66b-o_FvKxMTGXtcnnnHiMqe9Q) to join the Open-IM-Server Slack team channel. + +πŸ“§ **Gmail Contact**: If you have any questions, suggestions, or feedback for our open-source projects, please feel free to [contact us via email](https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=winxu81@gmail.com). + +πŸ“– **Blog**: Stay up-to-date with interview projects and trends by reading our [blog](https://interview.top/). We share the latest developments, tech trends, and other interesting information related to interview. + +πŸ“± **WeChat**: Add us on WeChat (QR Code) and indicate that you are a user or developer of Open-IM-Server. We'll process your request as soon as possible. + +Remember, your contributions play a vital role in making interview successful, and we look forward to your active participation in our community! πŸ™Œ \ No newline at end of file diff --git a/scripts/template/head.md.tmpl b/scripts/template/head.md.tmpl new file mode 100644 index 0000000..75150b7 --- /dev/null +++ b/scripts/template/head.md.tmpl @@ -0,0 +1,31 @@ +## Welcome to the {{ .Tag }} release of [interview](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }})!πŸŽ‰πŸŽ‰! + +We are excited to release {{.Tag}}, Branch: https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/tree/{{ .Tag }} , Git hash [{{ .ShortCommit }}], Install Address: [{{ .ReleaseURL }}]({{ .ReleaseURL }}) + +Learn more about versions of interview: + ++ We release logs are recorded on [✨CHANGELOG](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/CHANGELOG/CHANGELOG.md) + ++ For information on versions of interview and how to maintain branches, read [πŸ“šthis article](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/docs/conversions/version.md) + ++ If you wish to use mirroring, read interview's [🀲image management policy](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/docs/conversions/images.md) + +**Want to be one of them 😘?** + +

+ + + + + + + + + +

+ +> **Note** +> @openimbot and @kubbot have made great contributions to the community as community πŸ€–robots(@aicworld/bot), respectively. +> Thanks to the @aicworld/openim team for all their hard work on this release. +> Thank you to all the [πŸ’•developers and contributors](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/graphs/contributors), people from all over the world, interview brings us together +> Contributions to this project are welcome! Please see [CONTRIBUTING.md](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/CONTRIBUTING.md) for details. \ No newline at end of file diff --git a/scripts/template/project_README.md b/scripts/template/project_README.md new file mode 100644 index 0000000..96575e6 --- /dev/null +++ b/scripts/template/project_README.md @@ -0,0 +1,41 @@ +# Project myproject + + + +## Features + + + +## Getting Started + +### Prerequisites + + + +### Building + + + +### Running + + + +## Using + + + +## Contributing + + + +## Community(optional) + + + +## Authors + + + +## License + + diff --git a/server/README.md b/server/README.md new file mode 100644 index 0000000..99df164 --- /dev/null +++ b/server/README.md @@ -0,0 +1,9 @@ +# + +### Register + +- Use email to register. + +### Login + +- Use token genenrate from `server`. \ No newline at end of file diff --git a/server/cmd/interview/interview.go b/server/cmd/interview/interview.go new file mode 100644 index 0000000..afdeece --- /dev/null +++ b/server/cmd/interview/interview.go @@ -0,0 +1,15 @@ +// Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package interview diff --git a/server/config.docker.yaml b/server/config.docker.yaml new file mode 100644 index 0000000..8e9d56c --- /dev/null +++ b/server/config.docker.yaml @@ -0,0 +1,84 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +app: + version: 0.1.0-dev + debug: true + log_file: logs/ + +server: + ip: 0.0.0.0 + port: 10010 + max_file_size: 10 + +jwt: + secret: interview + issuer: interview + expire_days: 1 + +mysql: + ip: 177.8.0.3 + port: 3306 + username: root + password: 123123 + database: interview + max_lifetime: 120 + max_open_conns: 100 + max_idle_conns: 20 + +redis: + ip: 177.8.0.4 + port: 6379 + password: interview + database: 0 + +minio: + ip: 177.8.0.5 + port: 9000 + access_key_id: test123123 + secret_access_key: test123123 + bucket: interview + app_bucket: interview + location: us-east-1 + +influxdb: + ip: 177.8.0.6 + port: 8086 + token: admin1234 + org: interview + bucket: interview + +email: + host: # smtp address + port: 25 + from: # email address + nickname: interview + password: # smtp password + pool_size: 4 + +openim: + secret: interview + ip: 127.0.0.1 + api_port: 10002 + platform_id: 5 # web + admin_id: interview_admin # OpenIMServer admin userID + +slack: + bot_token: + app_token: + app_id: # need to give string, like '1821.42' + client_id: + client_secret: + signing_secret: + verification_token: \ No newline at end of file diff --git a/server/config.example.yaml b/server/config.example.yaml new file mode 100644 index 0000000..4043c7e --- /dev/null +++ b/server/config.example.yaml @@ -0,0 +1,84 @@ +# Copyright Β© 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +app: + version: 0.1.0-dev + debug: true + log_file: logs/ + +server: + ip: 127.0.0.1 + port: 10010 + max_file_size: 10 + +jwt: + secret: interview + issuer: interview + expire_days: 1 + +mysql: + ip: 177.8.0.3 + port: 3306 + username: root + password: 123123 + database: interview + max_lifetime: 120 + max_open_conns: 100 + max_idle_conns: 20 + +redis: + ip: 177.8.0.4 + port: 6379 + password: interview + database: 0 + +minio: + ip: 177.8.0.5 + port: 9000 + access_key_id: test123123 + secret_access_key: test123123 + bucket: interview + app_bucket: interview + location: us-east-1 + +influxdb: + ip: 177.8.0.6 + port: 8086 + token: admin1234 + org: interview + bucket: interview + +email: + host: # smtp address + port: 25 + from: # email address + nickname: interview + password: # smtp password + pool_size: 4 + +openim: + secret: openIM123 + ip: 127.0.0.1 + api_port: 10002 + platform_id: 5 # web + admin_id: openIMAdmin + +slack: + bot_token: + app_token: + app_id: # need to give string, like '1821.42' + client_id: + client_secret: + signing_secret: + verification_token: \ No newline at end of file diff --git a/server/docker_init_server.sh b/server/docker_init_server.sh new file mode 100644 index 0000000..0606df0 --- /dev/null +++ b/server/docker_init_server.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Copyright Β© 2024 interview & OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +./dbmigration -c ./config.docker.yaml +./server -c ./config.docker.yaml \ No newline at end of file diff --git a/server/docs/docs.go b/server/docs/docs.go new file mode 100644 index 0000000..ba72662 --- /dev/null +++ b/server/docs/docs.go @@ -0,0 +1,3 @@ +// Code generated by swaggo/swag. DO NOT EDIT. + +package docs diff --git a/server/examples/README.md b/server/examples/README.md new file mode 100644 index 0000000..ba10965 --- /dev/null +++ b/server/examples/README.md @@ -0,0 +1,9 @@ +# `/examples` + +Examples for your applications and/or public libraries. + +Examples: + +* https://github.com/nats-io/nats.go/tree/master/examples +* https://github.com/docker-slim/docker-slim/tree/master/examples +* https://github.com/hashicorp/packer/tree/master/examples \ No newline at end of file diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..ec65f8f --- /dev/null +++ b/server/go.mod @@ -0,0 +1,3 @@ +module github.com/aicworld/interview + +go 1.21.5 diff --git a/server/internal/README.md b/server/internal/README.md new file mode 100644 index 0000000..a84ac69 --- /dev/null +++ b/server/internal/README.md @@ -0,0 +1 @@ +# internal \ No newline at end of file diff --git a/server/pkg/OWNERS b/server/pkg/OWNERS new file mode 100644 index 0000000..a9521f7 --- /dev/null +++ b/server/pkg/OWNERS @@ -0,0 +1,4 @@ +reviewers: + - cubxxw +approvers: + - cubxxw \ No newline at end of file diff --git a/server/pkg/README.md b/server/pkg/README.md new file mode 100644 index 0000000..8fff56d --- /dev/null +++ b/server/pkg/README.md @@ -0,0 +1,55 @@ +# `/pkg` + +Library code that's ok to use by external applications (e.g., `/pkg/mypubliclib`). Other projects will import these libraries expecting them to work, so think twice before you put something here :-) Note that the `internal` directory is a better way to ensure your private packages are not importable because it's enforced by Go. The `/pkg` directory is still a good way to explicitly communicate that the code in that directory is safe for use by others. The [`I'll take pkg over internal`](https://travisjeffery.com/b/2019/11/i-ll-take-pkg-over-internal/) blog post by Travis Jeffery provides a good overview of the `pkg` and `internal` directories and when it might make sense to use them. + +It's also a way to group Go code in one place when your root directory contains lots of non-Go components and directories making it easier to run various Go tools (as mentioned in these talks: [`Best Practices for Industrial Programming`](https://www.youtube.com/watch?v=PTE4VJIdHPg) from GopherCon EU 2018, [GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps](https://www.youtube.com/watch?v=oL6JBUk6tj0) and [GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go](https://www.youtube.com/watch?v=3gQa1LWwuzk)). + +Note that this is not a universally accepted pattern and for every popular repo that uses it you can find 10 that don't. It's up to you to decide if you want to use this pattern or not. Regardless of whether or not it's a good pattern more people will know what you mean than not. It might a bit confusing for some of the new Go devs, but it's a pretty simple confusion to resolve and that's one of the goals for this project layout repo. + +Ok not to use it if your app project is really small and where an extra level of nesting doesn't add much value (unless you really want to). Think about it when it's getting big enough and your root directory gets pretty busy (especially if you have a lot of non-Go app components). + + +Examples: + +* https://github.com/jaegertracing/jaeger/tree/master/pkg +* https://github.com/istio/istio/tree/master/pkg +* https://github.com/GoogleContainerTools/kaniko/tree/master/pkg +* https://github.com/google/gvisor/tree/master/pkg +* https://github.com/google/syzkaller/tree/master/pkg +* https://github.com/perkeep/perkeep/tree/master/pkg +* https://github.com/heptio/ark/tree/master/pkg +* https://github.com/argoproj/argo/tree/master/pkg +* https://github.com/heptio/sonobuoy/tree/master/pkg +* https://github.com/helm/helm/tree/master/pkg +* https://github.com/kubernetes/kubernetes/tree/master/pkg +* https://github.com/kubernetes/kops/tree/master/pkg +* https://github.com/moby/moby/tree/master/pkg +* https://github.com/grafana/grafana/tree/master/pkg +* https://github.com/influxdata/influxdb/tree/master/pkg +* https://github.com/cockroachdb/cockroach/tree/master/pkg +* https://github.com/derekparker/delve/tree/master/pkg +* https://github.com/etcd-io/etcd/tree/master/pkg +* https://github.com/oklog/oklog/tree/master/pkg +* https://github.com/flynn/flynn/tree/master/pkg +* https://github.com/jesseduffield/lazygit/tree/master/pkg +* https://github.com/gopasspw/gopass/tree/master/pkg +* https://github.com/sosedoff/pgweb/tree/master/pkg +* https://github.com/GoogleContainerTools/skaffold/tree/master/pkg +* https://github.com/knative/serving/tree/master/pkg +* https://github.com/grafana/loki/tree/master/pkg +* https://github.com/bloomberg/goldpinger/tree/master/pkg +* https://github.com/Ne0nd0g/merlin/tree/master/pkg +* https://github.com/jenkins-x/jx/tree/master/pkg +* https://github.com/DataDog/datadog-agent/tree/master/pkg +* https://github.com/dapr/dapr/tree/master/pkg +* https://github.com/cortexproject/cortex/tree/master/pkg +* https://github.com/dexidp/dex/tree/master/pkg +* https://github.com/pusher/oauth2_proxy/tree/master/pkg +* https://github.com/pdfcpu/pdfcpu/tree/master/pkg +* https://github.com/weaveworks/kured/tree/master/pkg +* https://github.com/weaveworks/footloose/tree/master/pkg +* https://github.com/weaveworks/ignite/tree/master/pkg +* https://github.com/tmrts/boilr/tree/master/pkg +* https://github.com/kata-containers/runtime/tree/master/pkg +* https://github.com/okteto/okteto/tree/master/pkg +* https://github.com/solo-io/squash/tree/master/pkg \ No newline at end of file diff --git a/server/test/README.md b/server/test/README.md new file mode 100644 index 0000000..a8c5c5e --- /dev/null +++ b/server/test/README.md @@ -0,0 +1,6 @@ +# Test +### One-click Execute All Tests and Generate Reports +```shell +go test -coverprofile=coverage.out ../... +go tool cover -html=coverage.out -o coverage.local.html +``` diff --git a/server/tools/README.md b/server/tools/README.md new file mode 100644 index 0000000..3f729f8 --- /dev/null +++ b/server/tools/README.md @@ -0,0 +1,9 @@ +# `/tools` + +Supporting tools for this project. Note that these tools can import code from the `/pkg` and `/internal` directories. + +Examples: + +* https://github.com/istio/istio/tree/master/tools +* https://github.com/openshift/origin/tree/master/tools +* https://github.com/dapr/dapr/tree/master/tools \ No newline at end of file diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..b480fe2 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,35 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules* +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# openim-sdk-package +public/openIM.wasm +public/sql-wasm.wasm +public/wasm_exec.js + +src/utils/open-im-sdk-wasm \ No newline at end of file diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..88f3884 --- /dev/null +++ b/web/README.md @@ -0,0 +1,39 @@ +# interview + +## Recommended IDE Setup + +Run `bash scripts/setup.sh` to install OpenIM SDK for vite. + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). + +## Customize configuration + +See [Vite Configuration Reference](https://vitejs.dev/config/). + +Modify `.env` config. + +# https://doc.rentsoft.cn/sdks/Enum/LogLevel +- LogLevel + - Debug 5 + - Info 4 + - Warn 3 + - Error 2 + - Fatal 1 + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Compile and Minify for Production + +```sh +npm run build +```