├── .github ├── actions │ ├── list │ │ └── action.yml │ ├── add │ │ └── action.yml │ ├── product │ │ └── action.yml │ ├── configure-docker-containerd-image-store │ │ └── action.yml │ ├── install_qemu_user_static_from_debian │ │ └── action.yml │ ├── tags_for_older │ │ └── action.yml │ └── tags_for_latest │ │ └── action.yml └── workflows │ ├── build-image-using-copier.yml │ ├── build-image-on-swift-image-using-copier.yml │ └── docker-image-ci.yml ├── LICENSE ├── copier └── Dockerfile ├── Makefile └── README.md /.github/actions/list/action.yml: -------------------------------------------------------------------------------- 1 | name: 'list' 2 | description: 'convert json array to comma separated list' 3 | inputs: 4 | array: 5 | description: input json array 6 | required: true 7 | outputs: 8 | list: 9 | description: "list" 10 | value: ${{ steps.process.outputs.list }} 11 | runs: 12 | using: "composite" 13 | steps: 14 | - id: process 15 | run: | 16 | list="$( 17 | jq -c -n -r --argjson array '${{ inputs.array }}' '$array|join(",")' 18 | )" 19 | echo "list=${list}" >> $GITHUB_OUTPUT 20 | shell: bash 21 | -------------------------------------------------------------------------------- /.github/actions/add/action.yml: -------------------------------------------------------------------------------- 1 | name: 'add' 2 | description: 'add up to three json arrays' 3 | inputs: 4 | a: 5 | description: input a 6 | required: false 7 | default: '""' 8 | b: 9 | description: input b 10 | required: false 11 | default: '""' 12 | c: 13 | description: input c 14 | required: false 15 | default: '""' 16 | outputs: 17 | array: 18 | description: "array" 19 | value: ${{ steps.process.outputs.array }} 20 | runs: 21 | using: "composite" 22 | steps: 23 | - id: process 24 | run: | 25 | array="$( 26 | jq -c -n --argjson a '${{ inputs.a }}' --argjson b '${{ inputs.b }}' --argjson c '${{ inputs.c }}' ' 27 | def flatmap: .|flatten|map(select(. != "" and . != null)); 28 | [([$a]|flatmap)[], ([$b]|flatmap)[], ([$c]|flatmap)[]] 29 | ' 30 | )" 31 | echo "array=${array}" >> $GITHUB_OUTPUT 32 | shell: bash 33 | -------------------------------------------------------------------------------- /.github/actions/product/action.yml: -------------------------------------------------------------------------------- 1 | name: 'product' 2 | description: 'Cartesian product of two json arrays' 3 | inputs: 4 | a: 5 | description: input a 6 | required: false 7 | default: '""' 8 | b: 9 | description: input b 10 | required: false 11 | default: '""' 12 | sep: 13 | description: optional input separator 14 | required: false 15 | default: '""' 16 | outputs: 17 | product: 18 | description: "Cartesian product" 19 | value: ${{ steps.process.outputs.product }} 20 | runs: 21 | using: "composite" 22 | steps: 23 | - id: process 24 | run: | 25 | product="$( 26 | jq -c -n --argjson a '${{ inputs.a }}' --argjson b '${{ inputs.b }}' --argjson sep '${{ inputs.sep }}' ' 27 | def flatmap: .|flatten|map(select(. != "" and . != null)); 28 | [([$a]|flatmap)[]+$sep+([$b]|flatmap)[]] 29 | ' 30 | )" 31 | echo "product=${product}" >> $GITHUB_OUTPUT 32 | shell: bash 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Norio Nomura 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/actions/configure-docker-containerd-image-store/action.yml: -------------------------------------------------------------------------------- 1 | name: 'configure docker containerd image store' 2 | description: 'configure docker containerd image store' 3 | inputs: 4 | USE_CONTAINERD: 5 | description: use containerd as docker image store 6 | required: false 7 | default: 'true' 8 | runs: 9 | using: "composite" 10 | steps: 11 | - run: | 12 | # enable containerd image store 13 | ENABLE_CONTAINERD_IMAGE_STORE=${{ inputs.USE_CONTAINERD }} 14 | [ "$ENABLE_CONTAINERD_IMAGE_STORE" != 'false' ] \ 15 | && ENABLE_CONTAINERD_IMAGE_STORE=true \ 16 | || ENABLE_CONTAINERD_IMAGE_STORE=false 17 | 18 | # detect current configuration 19 | config=/etc/docker/daemon.json 20 | current=$((sudo cat "$config" 2>/dev/null || echo "{}")|jq '.features."containerd-snapshotter" // false') 21 | 22 | # update configuration if necessary 23 | [ "$current" = "$ENABLE_CONTAINERD_IMAGE_STORE" ] && exit 0 24 | jq_expression='.features."containerd-snapshotter" = '$ENABLE_CONTAINERD_IMAGE_STORE 25 | tmpfile=$(mktemp) && (sudo cat "$config" 2>/dev/null || echo "{}") | jq "$jq_expression" > "$tmpfile" 26 | mkdir -p $(dirname "$config") && (cat "$tmpfile" | sudo tee "$config") && rm "$tmpfile" 27 | 28 | # restart docker 29 | sudo systemctl restart docker || sudo journalctl -xeu docker.service 30 | echo --- 31 | docker info 32 | echo --- 33 | docker image ls 34 | echo --- 35 | sudo systemctl status docker 36 | shell: bash 37 | -------------------------------------------------------------------------------- /.github/actions/install_qemu_user_static_from_debian/action.yml: -------------------------------------------------------------------------------- 1 | name: 'install qemu-user-static from debian' 2 | description: 'install qemu-user-static from debian' 3 | inputs: 4 | VERSION: 5 | description: version of qemu-user-static 6 | required: false 7 | TARGET_RELEASE: 8 | default: bookworm 9 | description: target release specifying to apt-get install 10 | required: false 11 | runs: 12 | using: "composite" 13 | steps: 14 | - id: process 15 | run: | 16 | TARGET_RELEASE=${{ inputs.TARGET_RELEASE }} 17 | VERSION=${{ inputs.VERSION }} 18 | 19 | # install debian-archive-keyring 20 | keyring=/etc/apt/keyrings/debian-archive-keyring.gpg 21 | [ -f $keyring ] || curl https://ftp-master.debian.org/keys/archive-key-12.asc -o - | sudo gpg --dearmor -o $keyring 22 | 23 | # add debian sources 24 | debian_sources=/etc/apt/sources.list.d/debian-$TARGET_RELEASE.sources 25 | [ -f "$debian_sources" ] || sudo tee $debian_sources < /etc/apt/apt.conf.d/keep-cache 18 | ARG RUNTIME_IMAGE _TARGET_TRIPLE_ARCH 19 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-${RUNTIME_IMAGE/:/-}-${_TARGET_TRIPLE_ARCH} \ 20 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=apt-${RUNTIME_IMAGE/:/-}-${_TARGET_TRIPLE_ARCH} \ 21 | apt-get update && apt-get install -y \ 22 | libcurl4 \ 23 | libxml2 24 | RUN --mount=type=bind,target=/runtime,from=runtime <<'EOT' 25 | #!/bin/bash -eu 26 | sourcekit=/usr/lib/libsourcekitdInProc.so 27 | test -f "${sourcekit}" && exit # assume that the libraries exist 28 | dependencies_txt=$(realpath $(ldd "/runtime${sourcekit}" | awk '/=>/ && $3~/\/lib\/swift/{print $3}')) 29 | dependencies=() 30 | while read -r line; do dependencies+=("$line"); done <<< "${dependencies_txt}" 31 | for dependency in "${dependencies[@]}"; do 32 | dirname=$(dirname "${dependency}") 33 | test -d "${dirname#/runtime}" || mkdir -p "${dirname#/runtime}" 34 | cp -pv "${dependency}" "${dirname#/runtime}" 35 | done 36 | cp -pv /runtime$sourcekit $(dirname $sourcekit) 37 | EOT 38 | ARG TARGETARCH 39 | ADD swiftlint_linux_${TARGETARCH}.tar.gz / 40 | 41 | # Print Installed SwiftLint Version 42 | RUN ["swiftlint", "version"] 43 | RUN echo "_ = 0" | exec swiftlint --use-stdin 44 | CMD ["swiftlint", "lint"] 45 | -------------------------------------------------------------------------------- /.github/actions/tags_for_latest/action.yml: -------------------------------------------------------------------------------- 1 | name: 'tags for latest' 2 | description: 'Generate tags for latest' 3 | inputs: 4 | repositories: 5 | description: input image repositories 6 | required: true 7 | swift_version: 8 | description: input swift version 9 | required: true 10 | swift_version_aliases: 11 | description: input swift version aliases 12 | required: true 13 | swiftlint_revision: 14 | description: input swiftlint revision 15 | required: true 16 | outputs: 17 | tags: 18 | description: tags 19 | value: ${{ steps.tags_for_latest.outputs.list }} 20 | runs: 21 | using: "composite" 22 | steps: 23 | - id: swift_versions 24 | uses: ./.github/actions/add 25 | with: 26 | a: ${{ inputs.swift_version }} 27 | b: ${{ inputs.swift_version_aliases }} 28 | 29 | - id: swift_tags 30 | uses: ./.github/actions/product 31 | with: 32 | a: '"swift-"' 33 | b: ${{ steps.swift_versions.outputs.array }} 34 | 35 | - id: producted_tags 36 | uses: ./.github/actions/product 37 | with: 38 | a: ${{ inputs.swiftlint_revision }} 39 | b: ${{ steps.swift_tags.outputs.product }} 40 | sep: '"_"' 41 | 42 | - id: tags 43 | uses: ./.github/actions/add 44 | with: 45 | a: ${{ inputs.swiftlint_revision }} 46 | b: ${{ steps.swift_tags.outputs.product }} 47 | c: ${{ steps.producted_tags.outputs.product }} 48 | 49 | - id: repos_and_tags 50 | uses: ./.github/actions/product 51 | with: 52 | a: ${{ inputs.repositories }} 53 | b: ${{ steps.tags.outputs.array }} 54 | sep: '":"' 55 | 56 | - id: tag_array_for_latest 57 | uses: ./.github/actions/add 58 | with: 59 | a: ${{ inputs.repositories }} 60 | b: ${{ steps.repos_and_tags.outputs.product }} 61 | 62 | - id: tags_for_latest 63 | uses: ./.github/actions/list 64 | with: 65 | array: ${{ steps.tag_array_for_latest.outputs.array }} 66 | -------------------------------------------------------------------------------- /.github/workflows/build-image-using-copier.yml: -------------------------------------------------------------------------------- 1 | name: build image using copier 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | build-args: 7 | required: true 8 | type: string 9 | image_name: 10 | required: true 11 | type: string 12 | push: 13 | required: true 14 | type: string 15 | tags: 16 | required: true 17 | type: string 18 | secrets: 19 | DOCKERHUB_TOKEN: 20 | required: true 21 | 22 | jobs: 23 | build_image_using_copier: 24 | name: Build ${{ inputs.image_name }} image using copier 25 | runs-on: ubuntu-latest 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | 30 | - uses: actions/download-artifact@v4 31 | with: 32 | name: swiftlint_amd64 33 | path: copier 34 | 35 | - uses: actions/download-artifact@v4 36 | with: 37 | name: swiftlint_arm64 38 | path: copier 39 | 40 | - uses: ./.github/actions/install_qemu_user_static_from_debian 41 | 42 | - uses: ./.github/actions/configure-docker-containerd-image-store 43 | 44 | - run: echo "${{ inputs.tags }}" 45 | 46 | - name: Login to Docker Hub 47 | uses: docker/login-action@v3 48 | with: 49 | username: norionomura 50 | password: ${{ secrets.DOCKERHUB_TOKEN }} 51 | 52 | - name: Login to GitHub Container Registry 53 | uses: docker/login-action@v3 54 | with: 55 | registry: ghcr.io 56 | username: ${{ github.actor }} 57 | password: ${{ secrets.GITHUB_TOKEN }} 58 | 59 | - name: Set up Docker Buildx 60 | uses: docker/setup-buildx-action@v3 61 | with: 62 | version: latest 63 | 64 | - name: build image using copier 65 | uses: docker/build-push-action@v6 66 | with: 67 | build-args: ${{ inputs.build-args }} 68 | context: copier 69 | platforms: linux/amd64,linux/arm64 70 | push: ${{ inputs.push }} 71 | tags: ${{ inputs.tags }} 72 | cache-from: type=gha 73 | cache-to: type=gha,mode=max 74 | -------------------------------------------------------------------------------- /.github/workflows/build-image-on-swift-image-using-copier.yml: -------------------------------------------------------------------------------- 1 | name: build image on swift image using copier 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | latest: 7 | type: string 8 | push: 9 | required: true 10 | type: string 11 | repositories: 12 | required: true 13 | type: string 14 | swift_version: 15 | required: true 16 | type: string 17 | swift_version_aliases: 18 | type: string 19 | swiftlint_revision: 20 | required: true 21 | type: string 22 | secrets: 23 | DOCKERHUB_TOKEN: 24 | required: true 25 | 26 | jobs: 27 | build_tags: 28 | name: build tags for swift-${{ inputs.swift_version }} 29 | runs-on: ubuntu-latest 30 | outputs: 31 | tags: ${{ steps.tags.outputs.tags }} 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - id: latest_tags 36 | uses: ./.github/actions/tags_for_latest 37 | with: 38 | repositories: ${{ inputs.repositories }} 39 | swift_version: ${{ toJSON(inputs.swift_version) }} 40 | swift_version_aliases: ${{ inputs.swift_version_aliases }} 41 | swiftlint_revision: ${{ toJSON(inputs.swiftlint_revision) }} 42 | 43 | - id: older_tags 44 | uses: ./.github/actions/tags_for_older 45 | with: 46 | repositories: ${{ inputs.repositories }} 47 | swift_version: ${{ toJSON(inputs.swift_version) }} 48 | swift_version_aliases: ${{ inputs.swift_version_aliases }} 49 | swiftlint_revision: ${{ toJSON(inputs.swiftlint_revision) }} 50 | 51 | - id: tags 52 | run: echo "tags=${{ inputs.latest && steps.latest_tags.outputs.tags || steps.older_tags.outputs.tags }}" >> "$GITHUB_OUTPUT" 53 | 54 | build_image_on_swift_image_using_copier: 55 | name: Build image on swift-${{ inputs.swift_version }} 56 | needs: build_tags 57 | uses: ./.github/workflows/build-image-using-copier.yml 58 | with: 59 | image_name: swift-${{ inputs.swift_version }} 60 | build-args: | 61 | RUNTIME_IMAGE=swift:${{ inputs.swift_version }}-jammy 62 | tags: ${{ needs.build_tags.outputs.tags }} 63 | push: ${{ inputs.push }} 64 | secrets: inherit 65 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | IMAGE_NAME?=swiftlint 2 | 3 | override DOCKER_FLAGS+=--load 4 | 5 | # --no-cache-filter=$(NO_CACHE_FILTER) 6 | override DOCKER_FLAGS+=$(addprefix --no-cache-filter=,$(NO_CACHE_FILTER)) 7 | 8 | # --platform=$(PLATFORM) 9 | override PLATFORM?=linux/amd64,linux/arm64 10 | override DOCKER_FLAGS+=$(addprefix --platform=,$(PLATFORM)) 11 | 12 | # --progress=$(PROGRESS) 13 | override DOCKER_FLAGS+=$(addprefix --progress,$(PROGRESS)) 14 | 15 | # --build-arg= 16 | override DOCKER_FLAGS+=$(foreach v,$(_BUILD_ARGS),$(addprefix --build-arg=$(v)=,$($(v)))) 17 | override _BUILD_ARGS=$(sort $(_KNOWN_BUILD_ARG_VARS) $(_BUILD_ARG_VARS_FROM_CLI)) 18 | override _KNOWN_BUILD_ARG_VARS=CROSS PREFER_BUILDARCH RUNTIME_IMAGE TARGET_IMAGE USE_SDK 19 | override _BUILD_ARG_VARS_FROM_CLI=$(foreach v,$(filter-out $(_KNOWN_VARS),$(.VARIABLES)),$(if $(filter command line,$(origin $(v))),$(v))) 20 | override _KNOWN_VARS=CONTEXT DOCKER_FLAGS NO_CACHE_FILTER PLATFORM PROGRESS 21 | 22 | # --tag=[$(IMAGE_NAME):]$@ --tag=[$(IMAGE_NAME):]$(DOCKER_TAG) 23 | override DOCKER_FLAGS+=$(addprefix --tag=$(addsuffix :,$(IMAGE_NAME)),$(_DOCKER_TAGS)) 24 | override _DOCKER_TAGS+=$@ 25 | 26 | # --cache-to=, --cache-from= 27 | override DOCKER_FLAGS+=$(addsuffix $(_CACHE_FLAGS_COMMON),$(_CACHE_FLAGS)) 28 | override _CACHE_FLAGS_COMMON=${HOME}/.cache/docker,type=local,mode=max 29 | override _CACHE_FLAGS=--cache-to=dest= --cache-from=src= 30 | 31 | # docker --context $(CONTEXT) buildx build $(DOCKER_FLAGS) 32 | override BUILD=$(strip docker $(addprefix --context ,$(CONTEXT)) buildx build $(sort $(DOCKER_FLAGS))) 33 | 34 | .PHONY: all latest cross prefer-buildarch prefer-buildarch-use-sdk use-sdk copier slim 35 | 36 | all: latest cross native prefer-buildarch prefer-buildarch-use-sdk use-sdk copier slim 37 | 38 | test: ; echo $(addsuffix :,$(IMAGE_NAME)) 39 | 40 | # use builder 41 | latest: override _DOCKER_TAGS+=latest 42 | latest: prefer-buildarch 43 | 44 | cross: override CROSS=1 45 | cross: ; $(BUILD) builder 46 | 47 | native: ; $(BUILD) builder 48 | 49 | prefer-%: override PREFER_BUILDARCH=1 50 | %-sdk: override USE_SDK=1 51 | prefer-buildarch: ; $(BUILD) builder 52 | prefer-buildarch-use-sdk: ; $(BUILD) builder 53 | use-sdk: ; $(BUILD) builder 54 | 55 | # use copier 56 | override COPIER_ARTIFACTS=copier/swiftlint_linux_amd64.tar.gz copier/swiftlint_linux_arm64.tar.gz 57 | copier/swiftlint_linux_%.tar.gz: latest ; docker run --platform linux/$* --rm $(if $(IMAGE_NAME),$(IMAGE_NAME),latest) archive-swiftlint-runtime > $@ 58 | copier: $(COPIER_ARTIFACTS) ; $(BUILD) copier 59 | 60 | slim: override RUNTIME_IMAGE?=ubuntu 61 | slim: $(COPIER_ARTIFACTS) ; $(BUILD) copier 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-swiftlint 2 | 3 | *In this document, using **amd64, arm64** for platform architecture for docker, and **x86_64, aarch64** for Swift architecture.* 4 | 5 | ## `builder` directory 6 | ### Build without Swift SDK (no-sdk) 7 | 8 | #### Build image for docker host architecture 9 | ```bash 10 | docker buildx build --load builder/ -t swiftlint 11 | ``` 12 | 13 | #### Build multi-architecture image (x86_64-no-sdk, aarch64-no-sdk) 14 | ```bash 15 | docker buildx build --load builder/ -t swiftlint \ 16 | --platform linux/amd64,linux/arm64 17 | ``` 18 | 19 | ### Cross compilation on `BUILDER_IAMGE` using `TARGET_IMAGE` as Swift SDK 20 | Setup `TARGET_IMAGE` as the Swift SDK for the target architecture, and use them from Swift Toolchain in `BUILDER_IMAGE`. 21 | 22 | Supported combinations of `TARGET_IMAGE` and `BUILDER_IMAGE` are as follows: 23 | | | aarch64 builder | x86_64 builder | 24 | |----------------|--------------------|-------------------| 25 | | aarch64 target | aarch64-on-aarch64 | aarch64-on-x86_64 | 26 | | x86_64 target | x86_64-on-aarch64 | x86_64-on-x86_64 | 27 | 28 | 29 | #### Using `--build-arg USE_SDK=1` for building with Swift SDK 30 | Build arm64 architecture image using Swift SDK (aarch64-on-aarch64) 31 | ```bash 32 | docker buildx build --load builder/ -t swiftlint \ 33 | --platform linux/arm64 --build-arg USE_SDK=1 34 | ``` 35 | 36 | #### Using `--build-arg CROSS=1` for cross compilation with Swift SDK 37 | Build arm64 architecture image on amd64 architecture using Swift SDK (aarch64-on-x86_64) 38 | ```bash 39 | docker buildx build --load builder/ -t swiftlint \ 40 | --platform linux/arm64 --build-arg CROSS=1 41 | ``` 42 | 43 | #### Using `--build-arg CROSS_TARGETARCHS=...` for cross compiling target architectures with Swift SDK 44 | Build multi-architecture image, native compileed arm64 (aarch64-no-sdk), cross compiled amd64 (x86_64-on-aarch64). 45 | ```bash 46 | docker buildx build --load builder/ -t swiftlint \ 47 | --platform linux/amd64,linux/arm64 --build-arg CROSS_TARGETARCHS=amd64 48 | ``` 49 | This command minimizes the use of emulation on arm64 host. 50 | 51 | 52 | ## `copier` directory 53 | Expected to use `swiftlint` binary built in `builder` directory. 54 | 55 | ## Running aarch64 executable generated with Swift on x86_64 Ubuntu (GitHub Hosted Actions Runner) using `qemu-user-static` 56 | There is a known issue where running an aarch64 executable generated with Swift on x86_64 Ubuntu using the default `qemu-user-static` results in a crash. 57 | https://forums.swift.org/t/swift-runtime-unable-to-suspend-thread-when-compiling-in-qemu/67676 58 | 59 | This issue can be avoided by using qemu-user-static-7.2 distributed by Debian. 60 | There are two methods to install it: 61 | - For rootful docker, run `docker run --rm --privileged multiarch/qemu-user-static:7.2.0-1 --reset -p yes`. 62 | This method can be used as long as the docker installed on the GitHub Actions Runner is rootful. 63 | - Setup debian sources to apt on host and install it. See [install_qemu_user_static_from_debian](.github/actions/install_qemu_user_static_from_debian/action.yml) as an example. 64 | 65 | ## Author 66 | 67 | Norio Nomura 68 | 69 | ## License 70 | 71 | available under the MIT license. See the LICENSE file for more info. 72 | -------------------------------------------------------------------------------- /.github/workflows/docker-image-ci.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | create: 5 | push: 6 | branches: [master] 7 | paths: 8 | - '.github/actions/*/action.yml' 9 | - '.github/workflows/*.yml' 10 | - '*/Dockerfile' 11 | pull_request: 12 | paths: 13 | - '.github/actions/*/action.yml' 14 | - '.github/workflows/*.yml' 15 | - '*/Dockerfile' 16 | 17 | jobs: 18 | build_swiftlint: 19 | name: Build SwiftLint ${{ matrix.target_arch }} architecture 20 | runs-on: ${{ endsWith(matrix.target_arch, 'arm64') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} 21 | strategy: 22 | matrix: 23 | target_arch: ['amd64', 'arm64'] 24 | 25 | env: 26 | CONTAINER_REPOSITORIES: '["norionomura/swiftlint", "ghcr.io/norio-nomura/swiftlint"]' 27 | SWIFTLINT_REVISION: ${{ github.event_name == 'create' && github.event.ref_type == 'tag' && github.event.ref || '0.62.0' }} 28 | TARGET_SWIFT_VERSION: '6.2' 29 | 30 | outputs: 31 | push: ${{ github.event_name == 'create' && github.event.ref_type == 'tag' && 'true' || 'false' }} 32 | repositories: ${{ env.CONTAINER_REPOSITORIES }} 33 | swift_version: ${{ env.TARGET_SWIFT_VERSION }} 34 | swiftlint_revision: ${{ env.SWIFTLINT_REVISION }} 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | 39 | - uses: ./.github/actions/configure-docker-containerd-image-store 40 | 41 | - uses: docker/setup-buildx-action@v3 42 | with: 43 | version: latest 44 | 45 | - name: build ${{ matrix.target_arch }} architecture 46 | uses: docker/build-push-action@v6 47 | with: 48 | build-args: | 49 | BUILDER_IMAGE=swift:6.2-jammy 50 | FIX_SWIFTPM_7695=1 51 | PREFER_BUILDARCH=1 52 | SWIFTLINT_REVISION=${{ env.SWIFTLINT_REVISION }} 53 | TARGET_IMAGE=swift:${{ env.TARGET_SWIFT_VERSION }}-jammy 54 | context: builder 55 | load: true 56 | platforms: linux/${{ matrix.target_arch }} 57 | tags: swiftlint 58 | cache-from: type=gha 59 | cache-to: type=gha,mode=max 60 | 61 | - name: archive 62 | run: > 63 | docker run --platform linux/${{ matrix.target_arch }} --rm swiftlint archive-swiftlint-runtime 64 | > copier/swiftlint_linux_${{ matrix.target_arch }}.tar.gz 65 | 66 | - name: upload ${{ matrix.target_arch }} artifact 67 | uses: actions/upload-artifact@v4 68 | with: 69 | name: swiftlint_${{ matrix.target_arch }} 70 | path: copier/swiftlint_linux_${{ matrix.target_arch }}.tar.gz 71 | 72 | build_slim_tags: 73 | name: Build slim tags 74 | needs: build_swiftlint 75 | runs-on: ubuntu-latest 76 | outputs: 77 | tags: ${{ steps.slim_tag_list.outputs.list }} 78 | steps: 79 | - uses: actions/checkout@v4 80 | 81 | - id: slim_tags 82 | uses: ./.github/actions/product 83 | with: 84 | a: ${{ needs.build_swiftlint.outputs.repositories }} 85 | b: "[\"slim\", \"${{ needs.build_swiftlint.outputs.swiftlint_revision }}-slim\"]" 86 | sep: '":"' 87 | 88 | - id: slim_tag_list 89 | uses: ./.github/actions/list 90 | with: 91 | array: ${{ steps.slim_tags.outputs.product }} 92 | 93 | build_slim_image_using_copier: 94 | name: Build slim image using copier 95 | needs: [build_swiftlint, build_slim_tags] 96 | uses: ./.github/workflows/build-image-using-copier.yml 97 | with: 98 | image_name: slim 99 | build-args: | 100 | RUNTIME_IMAGE=ubuntu:jammy 101 | TARGET_IMAGE=swift:${{ needs.build_swiftlint.outputs.swift_version }}-jammy 102 | tags: ${{ needs.build_slim_tags.outputs.tags }} 103 | push: ${{ needs.build_swiftlint.outputs.push }} 104 | secrets: inherit 105 | 106 | build_images_on_swift_image: 107 | name: Build image on swift-${{ matrix.swift_version }} image 108 | needs: build_swiftlint 109 | strategy: 110 | fail-fast: false 111 | matrix: 112 | swift_version: ['5.9.0', '5.9.1', '5.9.2', '5.10.0', '5.10.1', '6.0.0', '6.0.1', '6.0.2', '6.0.3', '6.1.0', '6.1.1', '6.1.2', '6.1.3', '6.2.0'] 113 | include: 114 | - swift_version: '5.9.2' 115 | swift_version_aliases: ["5.9"] 116 | - swift_version: '5.10.1' 117 | swift_version_aliases: ["5", "5.10"] 118 | - swift_version: '6.0.3' 119 | swift_version_aliases: ["6.0"] 120 | - swift_version: '6.1.3' 121 | swift_version_aliases: ["6.1"] 122 | - swift_version: '6.2.0' 123 | swift_version_aliases: ["6", "6.2"] 124 | latest: 'true' 125 | 126 | uses: ./.github/workflows/build-image-on-swift-image-using-copier.yml 127 | with: 128 | latest: ${{ matrix.latest }} 129 | push: ${{ needs.build_swiftlint.outputs.push }} 130 | repositories: ${{ needs.build_swiftlint.outputs.repositories }} 131 | swift_version: ${{ matrix.swift_version }} 132 | swift_version_aliases: ${{ toJSON(matrix.swift_version_aliases) }} 133 | swiftlint_revision: ${{ needs.build_swiftlint.outputs.swiftlint_revision }} 134 | secrets: inherit 135 | --------------------------------------------------------------------------------