name: Build env: GO_VERSION: "1.25.8" on: push: branches: - master pull_request: jobs: go-tests: name: Running Go tests runs-on: ubuntu-latest services: mysql: image: mysql:5.7 env: MYSQL_DATABASE: casdoor MYSQL_ROOT_PASSWORD: 123456 ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: ./go.mod - name: Tests run: | go test -v $(go list ./...) -tags skipCi working-directory: ./ frontend: name: Front-end runs-on: ubuntu-latest needs: [go-tests] steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 20 cache: "yarn" cache-dependency-path: ./web/yarn.lock - run: yarn install && CI=false yarn run build working-directory: ./web - name: Upload build artifacts if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' uses: actions/upload-artifact@v4 with: name: frontend-build-${{ github.run_id }} path: ./web/build backend: name: Back-end runs-on: ubuntu-latest needs: [go-tests] steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: ./go.mod - run: go version - name: Build run: | go build -race -ldflags "-extldflags '-static'" working-directory: ./ linter: name: Go-Linter runs-on: ubuntu-latest needs: [go-tests] steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache: false - name: Sync vendor tree run: go mod vendor # CI and local `make lint` both use the repo's gofumpt-only golangci-lint config. - name: golangci-lint uses: golangci/golangci-lint-action@v9.2.0 with: version: v2.11.4 args: --config .golangci.yml ./... e2e: name: e2e-test runs-on: ubuntu-latest needs: [go-tests] services: mysql: image: mysql:5.7 env: MYSQL_DATABASE: casdoor MYSQL_ROOT_PASSWORD: 123456 ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: ./go.mod - name: start backend run: nohup go run ./main.go > /tmp/backend.log 2>&1 & working-directory: ./ - name: Wait for backend to be ready run: | echo "Waiting for backend server to start on port 8000..." for i in {1..60}; do if curl -s http://localhost:8000 > /dev/null 2>&1; then echo "Backend is ready!" break fi if [ $i -eq 60 ]; then echo "Backend failed to start within 60 seconds" echo "Backend logs:" cat /tmp/backend.log || echo "No backend logs available" exit 1 fi echo "Waiting... ($i/60)" sleep 1 done - uses: actions/setup-node@v3 with: node-version: 20 cache: "yarn" cache-dependency-path: ./web/yarn.lock - run: yarn install working-directory: ./web - uses: cypress-io/github-action@v5 with: browser: chrome start: yarn start wait-on: "http://localhost:7001" wait-on-timeout: 210 working-directory: ./web - uses: actions/upload-artifact@v4 if: failure() with: name: cypress-screenshots path: ./web/cypress/screenshots - uses: actions/upload-artifact@v4 if: always() with: name: cypress-videos path: ./web/cypress/videos tag-release: name: Create Tag runs-on: ubuntu-latest permissions: contents: write issues: write if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' needs: [frontend, backend, linter, e2e] outputs: new-release-published: ${{ steps.semantic.outputs.new_release_published }} new-release-version: ${{ steps.semantic.outputs.new_release_version }} steps: - name: Checkout uses: actions/checkout@v4 - name: Create Tag with Semantic Release id: semantic uses: cycjimmy/semantic-release-action@v4 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} github-release: name: GitHub Release runs-on: ubuntu-latest permissions: contents: write issues: write if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && needs.tag-release.outputs.new-release-published == 'true' needs: [tag-release] steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: ./go.mod - name: Free disk space uses: jlumbroso/free-disk-space@v1.3.1 with: tool-cache: false android: true dotnet: true haskell: true large-packages: true swap-storage: true - name: Download frontend build artifacts uses: actions/download-artifact@v4 with: name: frontend-build-${{ github.run_id }} path: ./web/build - name: Prepare Go caches run: | echo "GOMODCACHE=$RUNNER_TEMP/gomod" >> $GITHUB_ENV echo "GOCACHE=$RUNNER_TEMP/gocache" >> $GITHUB_ENV go clean -cache -modcache -testcache -fuzzcache - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: "~> v2" args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} docker-release: name: Docker Release runs-on: ubuntu-latest permissions: contents: write issues: write if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && needs.tag-release.outputs.new-release-published == 'true' needs: [tag-release] steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: -1 - name: Fetch Previous version id: get-previous-tag uses: actions-ecosystem/action-get-latest-tag@v1.6.0 - name: Decide Should_Push Or Not id: should_push run: | old_version=${{steps.get-previous-tag.outputs.tag}} new_version=${{ needs.tag-release.outputs.new-release-version }} old_array=(${old_version//\./ }) new_array=(${new_version//\./ }) if [ ${old_array[0]} != ${new_array[0]} ] then echo ::set-output name=push::'true' elif [ ${old_array[1]} != ${new_array[1]} ] then echo ::set-output name=push::'true' else echo ::set-output name=push::'false' fi - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up buildx id: buildx uses: docker/setup-buildx-action@v2 with: version: latest - name: Log in to Docker Hub uses: docker/login-action@v1 if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true' with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Push to Docker Hub uses: docker/build-push-action@v3 if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true' with: context: . target: STANDARD platforms: linux/amd64,linux/arm64 push: true tags: casbin/casdoor:${{ needs.tag-release.outputs.new-release-version }},casbin/casdoor:latest - name: Push All In One Version to Docker Hub uses: docker/build-push-action@v3 if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true' with: context: . target: ALLINONE platforms: linux/amd64,linux/arm64 push: true tags: casbin/casdoor-all-in-one:${{ needs.tag-release.outputs.new-release-version }},casbin/casdoor-all-in-one:latest - uses: actions/checkout@v3 if: steps.should_push.outputs.push=='true' with: repository: casdoor/casdoor-helm ref: "master" token: ${{ secrets.GH_BOT_TOKEN }} path: ./casdoor-helm - name: Update Helm Chart if: steps.should_push.outputs.push=='true' working-directory: ./casdoor-helm run: | # Set the appVersion and version of the chart to the current tag sed -i "s/appVersion: .*/appVersion: ${{ needs.tag-release.outputs.new-release-version }}/g" ./charts/casdoor/Chart.yaml sed -i "s/version: .*/version: ${{ needs.tag-release.outputs.new-release-version }}/g" ./charts/casdoor/Chart.yaml REGISTRY=oci://registry-1.docker.io/casbin cd charts/casdoor helm package . PKG_NAME=$(ls *.tgz) helm repo index . --url $REGISTRY --merge index.yaml helm push $PKG_NAME $REGISTRY rm $PKG_NAME # Commit and push the changes back to the repository git config --global user.name "casbin-bot" git config --global user.email "bot@casbin.org" git add Chart.yaml index.yaml git commit -m "chore(helm): bump helm charts appVersion to ${{ needs.tag-release.outputs.new-release-version }}" git tag ${{ needs.tag-release.outputs.new-release-version }} git push origin HEAD:master --follow-tags