From a02c959115bd5341406b4116ed673a7eba021005 Mon Sep 17 00:00:00 2001 From: Adam Bouqdib Date: Thu, 13 Aug 2020 18:22:24 +0100 Subject: [PATCH] chore: create multiarch docker image --- .github/workflows/fider.yml | 72 ++++++++++++++++++++++++++----------- Dockerfile | 6 +++- app/pkg/dbx/migrate.go | 28 +++++++-------- magefile.go | 5 +-- 4 files changed, 71 insertions(+), 40 deletions(-) diff --git a/.github/workflows/fider.yml b/.github/workflows/fider.yml index a415a94c9..a95f698b2 100644 --- a/.github/workflows/fider.yml +++ b/.github/workflows/fider.yml @@ -3,10 +3,10 @@ name: fider on: push: branches: - - master + - master pull_request: branches: - - master + - master jobs: test-ui: @@ -17,7 +17,7 @@ jobs: steps: - name: checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v2 - run: npm ci - run: mage lint:ui - run: mage test:ui @@ -32,7 +32,7 @@ jobs: minio: image: getfider/minio:0.0.2 ports: - - 9000:9000 + - 9000:9000 env: MINIO_ACCESS_KEY: s3user MINIO_SECRET_KEY: s3user-s3cr3t @@ -43,12 +43,12 @@ jobs: POSTGRES_PASSWORD: fider_ci_pw POSTGRES_DB: fider_ci ports: - - 5432:5432 + - 5432:5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v2 - run: mage lint:server - name: mage test:server run: | @@ -67,24 +67,54 @@ jobs: steps: - name: checkout code - uses: actions/checkout@v1 - - run: docker build -t getfider/fider . - - - name: extract branch name - run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" - id: getBranch + uses: actions/checkout@v2 - - uses: azure/docker-login@v1 - if: steps.getBranch.outputs.branch == 'master' + - name: set up docker buildx + uses: crazy-max/ghaction-docker-buildx@v3 + + - name: cache docker layers + uses: actions/cache@v2 with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASS }} + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: ${{ runner.os }}-buildx- + + - name: build docker image + run: | + docker buildx build \ + --cache-from "type=local,src=/tmp/.buildx-cache" \ + --cache-to "type=local,dest=/tmp/.buildx-cache" \ + --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64 \ + --output "type=image,push=false" \ + --tag getfider/fider . + + # fails when used with buildx - see https://github.com/crazy-max/ghaction-docker-buildx/issues/230 + # TODO: re-enable once issue above is fixed + # - uses: azure/docker-login@v1 + # if: github.ref == 'refs/heads/master' + # with: + # username: ${{ secrets.DOCKER_USER }} + # password: ${{ secrets.DOCKER_PASS }} + + - name: docker login + if: github.ref == 'refs/heads/master' + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USER }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASS }} + run: echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin - name: push docker image - if: steps.getBranch.outputs.branch == 'master' + if: github.ref == 'refs/heads/master' run: | export SHORT_SHA=`git rev-parse --short=7 ${GITHUB_SHA}` - docker tag getfider/fider getfider/fider:${SHORT_SHA} - docker push getfider/fider:${SHORT_SHA} - docker tag getfider/fider getfider/fider:master - docker push getfider/fider:master \ No newline at end of file + docker buildx build \ + --cache-from "type=local,src=/tmp/.buildx-cache" \ + --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64 \ + --tag getfider/fider:${SHORT_SHA} \ + --tag getfider/fider:master \ + --push . + + - name: cleanup + if: always() && github.ref == 'refs/heads/master' + run: | + rm -f ${HOME}/.docker/config.json diff --git a/Dockerfile b/Dockerfile index fd98f9ca9..857a7800d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ # Build Step FROM getfider/githubci:0.0.2 AS builder +ARG TARGETPLATFORM + RUN mkdir /app WORKDIR /app @@ -8,7 +10,9 @@ COPY . . RUN npm ci RUN node -v RUN npm -v -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 mage build +RUN GOARCH="$(echo $TARGETPLATFORM | cut -d '/' -f 2)" \ + GOARM="$(echo $TARGETPLATFORM | cut -d '/' -f 3 | tail -c 2)" \ + CGO_ENABLED=0 GOOS=linux mage build # Runtime Step FROM alpine:3.10 diff --git a/app/pkg/dbx/migrate.go b/app/pkg/dbx/migrate.go index bfd04cea2..95d04a99d 100644 --- a/app/pkg/dbx/migrate.go +++ b/app/pkg/dbx/migrate.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "os" "sort" - "strconv" "strings" "github.com/getfider/fider/app/models/dto" @@ -32,8 +31,8 @@ func Migrate(ctx context.Context, path string) error { return errors.Wrap(err, "failed to read files from dir '%s'", path) } - versions := make([]int, len(files)) - versionFiles := make(map[int]string, len(files)) + versions := make([]string, len(files)) + versionFiles := make(map[string]string, len(files)) for i, file := range files { fileName := file.Name() parts := strings.Split(fileName, "_") @@ -41,13 +40,10 @@ func Migrate(ctx context.Context, path string) error { return errors.New("migration file must have exactly 12 chars for version: '%s' is invalid.", fileName) } - versions[i], err = strconv.Atoi(parts[0]) + versions[i] = parts[0] versionFiles[versions[i]] = fileName - if err != nil { - return errors.Wrap(err, "failed to convert '%s' to number", parts[0]) - } } - sort.Ints(versions) + sort.Strings(versions) log.Infof(ctx, "Found total of @{Total} migration files.", dto.Props{ "Total": len(versions), @@ -90,7 +86,7 @@ func Migrate(ctx context.Context, path string) error { return nil } -func runMigration(ctx context.Context, version int, path, fileName string) error { +func runMigration(ctx context.Context, version string, path, fileName string) error { filePath := env.Path(path + "/" + fileName) content, err := ioutil.ReadFile(filePath) if err != nil { @@ -115,29 +111,29 @@ func runMigration(ctx context.Context, version int, path, fileName string) error return trx.Commit() } -func getLastMigration() (int, error) { +func getLastMigration() (string, error) { _, err := conn.Exec(`CREATE TABLE IF NOT EXISTS migrations_history ( version BIGINT PRIMARY KEY, filename VARCHAR(100) null, date TIMESTAMPTZ NOT NULL DEFAULT NOW() )`) if err != nil { - return 0, err + return "", err } - var lastVersion sql.NullInt64 - row := conn.QueryRow("SELECT MAX(version) FROM migrations_history LIMIT 1") + var lastVersion sql.NullString + row := conn.QueryRow("SELECT CAST(MAX(version) as varchar) FROM migrations_history LIMIT 1") err = row.Scan(&lastVersion) if err != nil { - return 0, err + return "", err } if !lastVersion.Valid { // If it's the first run, maybe we have records on old migrations table, so try to get from it. // This SHOULD be removed in the far future. - row := conn.QueryRow("SELECT version FROM schema_migrations LIMIT 1") + row := conn.QueryRow("SELECT CAST(version as varchar) FROM schema_migrations LIMIT 1") _ = row.Scan(&lastVersion) } - return int(lastVersion.Int64), nil + return lastVersion.String, nil } diff --git a/magefile.go b/magefile.go index e18427883..a033a073a 100644 --- a/magefile.go +++ b/magefile.go @@ -88,8 +88,9 @@ func (Build) All() { func (Build) Server() error { env := map[string]string{ - "GOOS": runtime.GOOS, - "GOARCH": runtime.GOARCH, + "GOOS": os.Getenv("GOOS"), + "GOARCH": os.Getenv("GOARCH"), + "GOARM": os.Getenv("GOARM"), } ldflags := "-s -w -X main.buildtime=" + buildTime + " -X main.buildnumber=" + buildNumber return sh.RunWith(env, "go", "build", "-ldflags", ldflags, "-o", exeName, ".")