diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4de1065..eab454c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,21 +12,23 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Go + - name: Setup bun + uses: oven-sh/setup-bun@v2 + + - name: Setup go uses: actions/setup-go@v5 with: go-version: "^1.23.2" - - name: Setup bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - name: Install frontend dependencies run: | cd frontend bun install + - name: Set version + run: | + echo testing > internal/assets/version + - name: Build frontend run: | cd frontend diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000..2df55a4 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,298 @@ +name: Nightly Release +on: + workflow_dispatch: + +jobs: + create-release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Delete old release + run: gh release delete --cleanup-tag --yes nightly || echo release not found + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + + - name: Create release + uses: softprops/action-gh-release@v2 + with: + prerelease: true + tag_name: nightly + + generate-metadata: + runs-on: ubuntu-latest + needs: create-release + outputs: + VERSION: ${{ steps.metadata.outputs.VERSION }} + COMMIT_HASH: ${{ steps.metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP: ${{ steps.metadata.outputs.BUILD_TIMESTAMP }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Generate metadata + id: metadata + run: | + echo "VERSION=nightly" >> "$GITHUB_OUTPUT" + echo "COMMIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + echo "BUILD_TIMESTAMP=$(date '+%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_OUTPUT" + + binary-build: + runs-on: ubuntu-latest + needs: + - create-release + - generate-metadata + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Install bun + uses: oven-sh/setup-bun@v2 + + - name: Install go + uses: actions/setup-go@v5 + with: + go-version: "^1.23.2" + + - name: Install frontend dependencies + run: | + cd frontend + bun install + + - name: Install backend dependencies + run: | + go mod download + + - name: Build frontend + run: | + cd frontend + bun run build + + - name: Build + run: | + cp -r frontend/dist internal/assets/dist + go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: tinyauth-amd64 + path: tinyauth-amd64 + + binary-build-arm: + runs-on: ubuntu-24.04-arm + needs: + - create-release + - generate-metadata + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Install bun + uses: oven-sh/setup-bun@v2 + + - name: Install go + uses: actions/setup-go@v5 + with: + go-version: "^1.23.2" + + - name: Install frontend dependencies + run: | + cd frontend + bun install + + - name: Install backend dependencies + run: | + go mod download + + - name: Build frontend + run: | + cd frontend + bun run build + + - name: Build + run: | + cp -r frontend/dist internal/assets/dist + go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: tinyauth-arm64 + path: tinyauth-arm64 + + image-build: + runs-on: ubuntu-latest + needs: + - create-release + - generate-metadata + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/tinyauth + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v6 + id: build + with: + platforms: linux/amd64 + labels: ${{ steps.meta.outputs.labels }} + tags: ghcr.io/${{ github.repository_owner }}/tinyauth + outputs: type=image,push-by-digest=true,name-canonical=true,push=true + build-args: | + VERSION=${{ needs.generate-metadata.outputs.VERSION }} + COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-linux-amd64 + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + image-build-arm: + runs-on: ubuntu-24.04-arm + needs: + - create-release + - generate-metadata + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/tinyauth + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set version + run: | + echo nightly > internal/assets/version + + - name: Build and push + uses: docker/build-push-action@v6 + id: build + with: + platforms: linux/arm64 + labels: ${{ steps.meta.outputs.labels }} + tags: ghcr.io/${{ github.repository_owner }}/tinyauth + outputs: type=image,push-by-digest=true,name-canonical=true,push=true + build-args: | + VERSION=${{ needs.generate-metadata.outputs.VERSION }} + COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-linux-arm64 + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + image-merge: + runs-on: ubuntu-latest + needs: + - image-build + - image-build-arm + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/tinyauth + tags: | + type=raw,nightly + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'ghcr.io/${{ github.repository_owner }}/tinyauth@sha256:%s ' *) + + update-release: + runs-on: ubuntu-latest + needs: + - binary-build + - binary-build-arm + steps: + - uses: actions/download-artifact@v4 + with: + pattern: tinyauth-* + path: binaries + merge-multiple: true + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: binaries/* + tag_name: nightly diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 33e63de..e233e45 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,17 +6,38 @@ on: - "v*" jobs: + generate-metadata: + runs-on: ubuntu-latest + outputs: + VERSION: ${{ steps.metadata.outputs.VERSION }} + COMMIT_HASH: ${{ steps.metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP: ${{ steps.metadata.outputs.BUILD_TIMESTAMP }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: nightly + + - name: Generate metadata + id: metadata + run: | + echo "VERSION=nightly" >> "$GITHUB_OUTPUT" + echo "COMMIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + echo "BUILD_TIMESTAMP=$(date '+%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_OUTPUT" + binary-build: runs-on: ubuntu-latest + needs: + - generate-metadata steps: - name: Checkout uses: actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest + - name: Install bun + uses: oven-sh/setup-bun@v2 - - uses: actions/setup-go@v5 + - name: Install go + uses: actions/setup-go@v5 with: go-version: "^1.23.2" @@ -27,7 +48,7 @@ jobs: - name: Install backend dependencies run: | - go mod tidy + go mod download - name: Build frontend run: | @@ -37,7 +58,7 @@ jobs: - name: Build run: | cp -r frontend/dist internal/assets/dist - CGO_ENABLED=0 go build -ldflags "-s -w" -o tinyauth-amd64 + go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64 - name: Upload artifact uses: actions/upload-artifact@v4 @@ -47,15 +68,17 @@ jobs: binary-build-arm: runs-on: ubuntu-24.04-arm + needs: + - generate-metadata steps: - name: Checkout uses: actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest + - name: Install bun + uses: oven-sh/setup-bun@v2 - - uses: actions/setup-go@v5 + - name: Install go + uses: actions/setup-go@v5 with: go-version: "^1.23.2" @@ -66,7 +89,7 @@ jobs: - name: Install backend dependencies run: | - go mod tidy + go mod download - name: Build frontend run: | @@ -76,7 +99,7 @@ jobs: - name: Build run: | cp -r frontend/dist internal/assets/dist - CGO_ENABLED=0 go build -ldflags "-s -w" -o tinyauth-arm64 + go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64 - name: Upload artifact uses: actions/upload-artifact@v4 @@ -86,6 +109,8 @@ jobs: image-build: runs-on: ubuntu-latest + needs: + - generate-metadata steps: - name: Checkout uses: actions/checkout@v4 @@ -114,6 +139,10 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true + build-args: | + VERSION=${{ needs.generate-metadata.outputs.VERSION }} + COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - name: Export digest run: | @@ -131,6 +160,8 @@ jobs: image-build-arm: runs-on: ubuntu-24.04-arm + needs: + - generate-metadata steps: - name: Checkout uses: actions/checkout@v4 @@ -159,6 +190,10 @@ jobs: labels: ${{ steps.meta.outputs.labels }} tags: ghcr.io/${{ github.repository_owner }}/tinyauth outputs: type=image,push-by-digest=true,name-canonical=true,push=true + build-args: | + VERSION=${{ needs.generate-metadata.outputs.VERSION }} + COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }} + BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }} - name: Export digest run: | diff --git a/.gitignore b/.gitignore index 85a9ff8..8cb2bae 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,7 @@ secret_oauth.txt .env # tmp directory -tmp \ No newline at end of file +tmp + +# version files +internal/assets/version \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e664a0..079d181 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -Contributing is relatively easy, you just need to follow the steps carefully and you will be up and running with a development server in less than 5 minutes. +Contributing is relatively easy, you just need to follow the steps below and you will be up and running with a development server in less than five minutes. ## Requirements @@ -20,7 +20,7 @@ cd tinyauth ## Install requirements -Although you will not need the requirements in your machine since the development will happen in docker, I still recommend to install them because this way you will not have import errors, to install the go requirements, run: +Although you will not need the requirements in your machine since the development will happen in docker, I still recommend to install them because this way you will not have import errors. To install the go requirements run: ```sh go mod tidy @@ -35,7 +35,7 @@ bun install ## Create your `.env` file -In order to configure the app you need to create an environment file, this can be done by copying the `.env.example` file to `.env` and modifying the environment variables inside to suit your needs. +In order to configure the app you need to create an environment file, this can be done by copying the `.env.example` file to `.env` and modifying the environment variables to suit your needs. ## Developing @@ -46,11 +46,14 @@ I have designed the development workflow to be entirely in docker, this is becau dev.example.com -> 127.0.0.1 ``` -Then you can just make sure the domains are correct in the example docker compose file and run: +> [!TIP] +> You can use [sslip.io](https://sslip.io) as a domain if you don't have one to develop with. + +Then you can just make sure the domains are correct in the development docker compose file and run: ```sh docker compose -f docker-compose.dev.yml up --build ``` > [!NOTE] -> I would recommend copying the example `docker-compose.dev.yml` into a `docker-compose.test.yml` file, so as you don't accidentally commit any sensitive information. +> I recommend copying the example `docker-compose.dev.yml` into a `docker-compose.test.yml` file, so as you don't accidentally commit any sensitive information. diff --git a/Dockerfile b/Dockerfile index 15a227d..db1f3b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,8 @@ +# Arguments +ARG VERSION +ARG COMMIT_HASH +ARG BUILD_TIMESTAMP + # Site builder FROM oven/bun:1.2.12-alpine AS frontend-builder @@ -34,8 +39,8 @@ COPY ./cmd ./cmd COPY ./internal ./internal COPY --from=frontend-builder /frontend/dist ./internal/assets/dist -RUN CGO_ENABLED=0 go build -ldflags "-s -w" - +RUN go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${VERSION} -X tinyauth/internal/constants.CommitHash=${COMMIT_HASH} -X tinyauth/internal/constants.BuildTimestamp=${BUILD_TIMESTAMP}" + # Runner FROM alpine:3.21 AS runner diff --git a/README.md b/README.md index 7a95ef4..4941651 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@
License Release - Commit activity Issues Tinyauth CI diff --git a/cmd/root.go b/cmd/root.go index 082b77b..d56247d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -8,8 +8,8 @@ import ( totpCmd "tinyauth/cmd/totp" userCmd "tinyauth/cmd/user" "tinyauth/internal/api" - "tinyauth/internal/assets" "tinyauth/internal/auth" + "tinyauth/internal/constants" "tinyauth/internal/docker" "tinyauth/internal/handlers" "tinyauth/internal/hooks" @@ -50,7 +50,7 @@ var rootCmd = &cobra.Command{ // Logger log.Logger = log.Level(zerolog.Level(config.LogLevel)) - log.Info().Str("version", assets.Version).Msg("Starting tinyauth") + log.Info().Str("version", strings.TrimSpace(constants.Version)).Msg("Starting tinyauth") // Users log.Info().Msg("Parsing users") diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..0c6f600 --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,24 @@ +package cmd + +import ( + "fmt" + "tinyauth/internal/constants" + + "github.com/spf13/cobra" +) + +// Create the version command +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version number of Tinyauth", + Long: `All software has versions. This is Tinyauth's`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Version: %s\n", constants.Version) + fmt.Printf("Commit Hash: %s\n", constants.CommitHash) + fmt.Printf("Build Timestamp: %s\n", constants.BuildTimestamp) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/go.mod b/go.mod index d33cd0d..e514646 100644 --- a/go.mod +++ b/go.mod @@ -85,7 +85,7 @@ require ( github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pquerna/otp v1.4.0 + github.com/pquerna/otp v1.5.0 github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/go.sum b/go.sum index b4344e4..61acac0 100644 --- a/go.sum +++ b/go.sum @@ -190,8 +190,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg= -github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs= +github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= diff --git a/internal/assets/assets.go b/internal/assets/assets.go index fc88051..6918867 100644 --- a/internal/assets/assets.go +++ b/internal/assets/assets.go @@ -8,8 +8,3 @@ import ( // //go:embed dist var Assets embed.FS - -// Version file -// -//go:embed version -var Version string diff --git a/internal/assets/version b/internal/assets/version deleted file mode 100644 index e682ea4..0000000 --- a/internal/assets/version +++ /dev/null @@ -1 +0,0 @@ -v3.3.0 \ No newline at end of file diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 72480b6..00b6feb 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -16,3 +16,8 @@ type Claims struct { PreferredUsername string `json:"preferred_username"` Groups []string `json:"groups"` } + +// Version information +var Version = "development" +var CommitHash = "n/a" +var BuildTimestamp = "n/a"