├── .github ├── actions │ ├── add │ │ └── action.yml │ ├── configure-docker-containerd-image-store │ │ └── action.yml │ ├── install_qemu_user_static_from_debian │ │ └── action.yml │ ├── list │ │ └── action.yml │ ├── product │ │ └── action.yml │ ├── tags_for_latest │ │ └── action.yml │ └── tags_for_older │ │ └── action.yml └── workflows │ ├── build-image-on-swift-image-using-copier.yml │ ├── build-image-using-copier.yml │ └── docker-image-ci.yml ├── LICENSE ├── Makefile ├── README.md ├── builder ├── Dockerfile └── swift-sdks.artifactbundle │ ├── aarch64-on-aarch64 │ ├── swift-sdk.json │ └── toolset.json │ ├── aarch64-on-x86_64 │ ├── swift-sdk.json │ └── toolset.json │ ├── info.json │ ├── x86_64-on-aarch64 │ ├── swift-sdk.json │ └── toolset.json │ └── x86_64-on-x86_64 │ ├── swift-sdk.json │ └── toolset.json └── copier └── Dockerfile /.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/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-11.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 <> $GITHUB_OUTPUT 20 | shell: bash 21 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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/actions/tags_for_older/action.yml: -------------------------------------------------------------------------------- 1 | name: 'tags for older' 2 | description: 'Generate tags for older swift versions' 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_builder.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: ${{ steps.swift_tags.outputs.product }} 46 | b: ${{ steps.producted_tags.outputs.product }} 47 | 48 | - id: repos_and_tags 49 | uses: ./.github/actions/product 50 | with: 51 | a: ${{ inputs.repositories }} 52 | b: ${{ steps.tags.outputs.array }} 53 | sep: '":"' 54 | 55 | - id: tags_for_builder 56 | uses: ./.github/actions/list 57 | with: 58 | array: ${{ steps.repos_and_tags.outputs.product }} 59 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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/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.59.0' }} 28 | TARGET_SWIFT_VERSION: '6.1' 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.1-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.8.0', '5.8.1', '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'] 113 | include: 114 | - swift_version: '5.8.1' 115 | swift_version_aliases: ["5.8"] 116 | - swift_version: '5.9.2' 117 | swift_version_aliases: ["5.9"] 118 | - swift_version: '5.10.1' 119 | swift_version_aliases: ["5", "5.10"] 120 | - swift_version: '6.0.3' 121 | swift_version_aliases: ["6.0"] 122 | - swift_version: '6.1.0' 123 | swift_version_aliases: ["6", "6.1"] 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /builder/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | #################################################################################################### 4 | # Build Arguments 5 | #################################################################################################### 6 | 7 | # Suffix for the default image names. 8 | ARG IMAGE_SUFFIX 9 | 10 | # The image to use for building SwiftLint by using Swift SDK 11 | ARG BUILDER_IMAGE=swift:6.1${IMAGE_SUFFIX} 12 | 13 | # The image to using Swift Toolchain for building SwiftLint 14 | ARG TARGET_IMAGE=swift:6.1${IMAGE_SUFFIX} 15 | 16 | # The image to running SwiftLint. If image does not contain Swift runtime libraries, 17 | # the libraries will be copied from the target image. 18 | ARG RUNTIME_IMAGE=${TARGET_IMAGE} 19 | 20 | # The revision of SwiftLint to build. 21 | ARG SWIFTLINT_REVISION=0.59.0 22 | 23 | # If set, target will be built on BUILDARCH. 24 | ARG PREFER_BUILDARCH 25 | 26 | # supports: amd64, x86_64, arm64, aarch64 27 | ARG CROSS_TARGETARCHS 28 | 29 | # If set, build target will be cross-compiled. 30 | # default: decided by the CROSS_TARGETARCHS 31 | ARG CROSS 32 | 33 | # If set, build target with verbose output. 34 | ARG VERBOSE 35 | 36 | # If set, build target by using Swift SDK. 37 | ARG USE_SDK 38 | 39 | # If set, build halt after building SwiftLint for debugging. 40 | ARG SLEEP 41 | 42 | # If set, Avoid link error fixed in https://github.com/apple/swift-package-manager/pull/7695 43 | ARG FIX_SWIFTPM_7695 44 | 45 | #################################################################################################### 46 | # Internal build arguments 47 | #################################################################################################### 48 | 49 | # Decide _TARGET_TRIPLE_ARCH from TARGETARCH 50 | ARG _TARGET_TRIPLE_ARCH=${TARGETARCH} 51 | ARG _TARGET_TRIPLE_ARCH=${_TARGET_TRIPLE_ARCH/*arm64/aarch64} 52 | ARG _TARGET_TRIPLE_ARCH=${_TARGET_TRIPLE_ARCH/*amd64/x86_64} 53 | 54 | ARG _HOST_TRIPLE_ARCH=${BUILDARCH} 55 | ARG _HOST_TRIPLE_ARCH=${_HOST_TRIPLE_ARCH/*arm64/aarch64} 56 | ARG _HOST_TRIPLE_ARCH=${_HOST_TRIPLE_ARCH/*amd64/x86_64} 57 | 58 | ARG _PARSE_PREFER_BUILDARCH=${PREFER_BUILDARCH} 59 | ARG _PARSE_PREFER_BUILDARCH=${_PARSE_PREFER_BUILDARCH:+${_HOST_TRIPLE_ARCH}} 60 | ARG _PARSE_PREFER_BUILDARCH=${_PARSE_PREFER_BUILDARCH:-${_TARGET_TRIPLE_ARCH}} 61 | ARG _PARSE_PREFER_BUILDARCH=${_TARGET_TRIPLE_ARCH/${_PARSE_PREFER_BUILDARCH}/} 62 | 63 | ARG CROSS_TARGETARCHS=${CROSS_TARGETARCHS:+${CROSS_TARGETARCHS},${_PARSE_PREFER_BUILDARCH}} 64 | ARG CROSS_TARGETARCHS=${CROSS_TARGETARCHS:-${_PARSE_PREFER_BUILDARCH}} 65 | 66 | # Parse CROSS_TARGETARCHS 67 | # input check requires `syntax=docker/dockerfile-upstream:master` 68 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${CROSS_TARGETARCHS} 69 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//arm64/} 70 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//amd64/} 71 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//aarch64/} 72 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//x86_64/} 73 | # ARG _UNSUPPORTED_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS} 74 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//,/} 75 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS:+UNSUPPORTED} 76 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS:-SUPPORTED} 77 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS//UNSUPPORTED/} 78 | # ARG _INPUT_CHECK_CROSS_TARGETARCHS=${_INPUT_CHECK_CROSS_TARGETARCHS:?"Unsupported ARCH detected: $_UNSUPPORTED_CROSS_TARGETARCHS"} 79 | 80 | ARG _PARSE_CROSS_TARGETARCHS=${CROSS_TARGETARCHS} 81 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//${_TARGET_TRIPLE_ARCH}/cross-arch} 82 | ARG _CROSS_TRIPLE_ARCH_VARIANT=${_TARGET_TRIPLE_ARCH} 83 | ARG _CROSS_TRIPLE_ARCH_VARIANT=${_CROSS_TRIPLE_ARCH_VARIANT/aarch64/arm64} 84 | ARG _CROSS_TRIPLE_ARCH_VARIANT=${_CROSS_TRIPLE_ARCH_VARIANT/x86_64/amd64} 85 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//${_CROSS_TRIPLE_ARCH_VARIANT}/cross-arch} 86 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//arm64/} 87 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//amd64/} 88 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//aarch64/} 89 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//x86_64/} 90 | ARG _PARSE_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS//,/} 91 | ARG _RESULT_PARSING_CROSS_TARGETARCHS=${_PARSE_CROSS_TARGETARCHS:+cross-arch} 92 | 93 | # Parse CROSS 94 | ARG CROSS=${_RESULT_PARSING_CROSS_TARGETARCHS:+1} 95 | # if `CROSS` is set then `_CROSS_OR_SAME` will be "cross-arch", otherwise the variable is the empty string. 96 | ARG _CROSS_OR_SAME=${CROSS:+cross-arch} 97 | # if `_CROSS_OR_SAME` is set then the variable will be that value. 98 | # If the variable is not set then the variable will be the "same-arch". 99 | ARG _CROSS_OR_SAME=${_CROSS_OR_SAME:-same-arch} 100 | 101 | # Parse USE_SDK 102 | ARG USE_SDK=${CROSS:+1} 103 | ARG _BUILDER_SELECTOR=${USE_SDK:+${_CROSS_OR_SAME}-sdk} 104 | ARG _BUILDER_SELECTOR=${_BUILDER_SELECTOR:-no-sdk} 105 | 106 | # Decide _BUILDER_TRIPLE_ARCH from CROSS and TARGETARCH 107 | ARG _BUILDER_TRIPLE_ARCH=${USE_SDK:+${_TARGET_TRIPLE_ARCH}${_CROSS_OR_SAME}} 108 | ARG _BUILDER_TRIPLE_ARCH=${_BUILDER_TRIPLE_ARCH/aarch64cross-arch/x86_64} 109 | ARG _BUILDER_TRIPLE_ARCH=${_BUILDER_TRIPLE_ARCH/aarch64same-arch/aarch64} 110 | ARG _BUILDER_TRIPLE_ARCH=${_BUILDER_TRIPLE_ARCH/x86_64cross-arch/aarch64} 111 | ARG _BUILDER_TRIPLE_ARCH=${_BUILDER_TRIPLE_ARCH/x86_64same-arch/x86_64} 112 | 113 | ARG _RUNTIME_NAME=${RUNTIME_IMAGE/:/-} 114 | ARG _SDK_NAME=${USE_SDK:+${_TARGET_TRIPLE_ARCH}-on-${_BUILDER_TRIPLE_ARCH}} 115 | ARG _SDK_NAME=${_SDK_NAME:-${_TARGET_TRIPLE_ARCH}-no-sdk} 116 | ARG _TARGET_NAME=${TARGET_IMAGE/:/-} 117 | 118 | ARG _BUILD_CACHE_ID=${USE_SDK:+build-${_SDK_NAME}-${BUILDER_IMAGE/:/-}} 119 | ARG _BUILD_CACHE_ID=${_BUILD_CACHE_ID:-build-${_SDK_NAME}-${_TARGET_NAME}} 120 | 121 | ARG _SLEEP_SELECTOR=${SLEEP:+-to-sleep} 122 | 123 | #################################################################################################### 124 | # Stages for Swift SDKs 125 | #################################################################################################### 126 | FROM scratch AS swift-sdk-tools 127 | # Install packages for Swift SDK 128 | COPY --chmod=755 <<'EOT' /install-packages 129 | #!/bin/bash -eux 130 | apt-get update && apt-get install -y \ 131 | binutils-aarch64-linux-gnu \ 132 | binutils-x86-64-linux-gnu \ 133 | libcurl4-openssl-dev \ 134 | libxml2-dev 135 | EOT 136 | # Fix symbolic linked libraries from absolute path to relative path for *-linux-gnu-ld.gold 137 | COPY --chmod=755 <<'EOT' /fix-symlinked-libraries-from-absolute-to-relative 138 | #!/bin/bash -eu 139 | for target_dir in $(readlink -f /lib/*-linux-gnu /lib*); do \ 140 | for target in $(find $target_dir -type l); do \ 141 | [[ ! "$(readlink $target)" =~ ^/ ]] || ln -sfv $(realpath --relative-to=$target_dir $target) $target; \ 142 | done; \ 143 | done 144 | EOT 145 | # Create SDKSettings.json 146 | COPY --chmod=755 <<'EOT' /create-sdk-settings-json 147 | #!/bin/bash -eux 148 | arch=$(arch) 149 | cat < /etc/apt/apt.conf.d/keep-cache 171 | ARG _TARGET_NAME 172 | ARG APT_CACHE_ID=apt-${_TARGET_NAME}-aarch64 173 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${APT_CACHE_ID} \ 174 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=${APT_CACHE_ID} \ 175 | --mount=type=bind,target=/swift-sdk-tools,from=swift-sdk-tools \ 176 | /swift-sdk-tools/prepare-sdk-root 177 | 178 | FROM --platform=linux/amd64 ${TARGET_IMAGE} AS swift-x86_64 179 | RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache 180 | ARG _TARGET_NAME 181 | ARG APT_CACHE_ID=apt-${_TARGET_NAME}-x86_64 182 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${APT_CACHE_ID} \ 183 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=${APT_CACHE_ID} \ 184 | --mount=type=bind,target=/swift-sdk-tools,from=swift-sdk-tools \ 185 | /swift-sdk-tools/prepare-sdk-root 186 | 187 | #################################################################################################### 188 | # Stages for building target with Swift SDK on same architecture 189 | #################################################################################################### 190 | # Builder uses same architectures to build SwiftLint 191 | FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS aarch64-on-aarch64-base 192 | FROM --platform=linux/amd64 ${BUILDER_IMAGE} AS x86_64-on-x86_64-base 193 | # Fix symbolic linked libraries from absolute path to relative path for *-linux-gnu-ld.gold 194 | RUN target_lib=/usr/lib64/ld-linux-x86-64.so.2 && \ 195 | test -L $target_lib && ln -sf $(realpath --relative-to=$(dirname $target_lib) $target_lib) $target_lib 196 | 197 | #################################################################################################### 198 | # Stages for building target with Swift SDK on other architecture 199 | #################################################################################################### 200 | # Builder uses other architectures to build SwiftLint 201 | FROM --platform=linux/amd64 ${BUILDER_IMAGE} AS aarch64-on-x86_64-base 202 | FROM --platform=linux/arm64 ${BUILDER_IMAGE} AS x86_64-on-aarch64-base 203 | 204 | #################################################################################################### 205 | # Stages for building target with no Swift SDK 206 | #################################################################################################### 207 | FROM --platform=linux/arm64 ${TARGET_IMAGE} AS aarch64-no-sdk-base 208 | FROM --platform=linux/amd64 ${TARGET_IMAGE} AS x86_64-no-sdk-base 209 | 210 | #################################################################################################### 211 | # Prepare source code for building SwiftLint 212 | #################################################################################################### 213 | FROM ${_SDK_NAME}-base AS base-preparer 214 | ARG _BUILD_CACHE_ID _BUILDER_SELECTOR _BUILDER_TRIPLE_ARCH _CROSS_OR_SAME _PARSE_CROSS_TARGETARCHS _RESULT_PARSING_CROSS_TARGETARCHS _RUNTIME_NAME _SDK_NAME _SLEEP_SELECTOR _TARGET_NAME _TARGET_TRIPLE_ARCH BUILDER_IMAGE CROSS CROSS_TARGETARCHS IMAGE_SUFFIX RUNTIME_IMAGE SLEEP SWIFTLINT_REVISION TARGET_IMAGE USE_SDK VERBOSE 215 | RUN [ -z "${VERBOSE}"] || cat < /etc/apt/apt.conf.d/keep-cache 268 | ARG _BUILDER_TRIPLE_ARCH 269 | ARG APT_CACHE_ID=apt-${_TARGET_NAME}-${_BUILDER_TRIPLE_ARCH} 270 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${APT_CACHE_ID} \ 271 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=${APT_CACHE_ID} \ 272 | [ -n "${VERBOSE}" ] && \ 273 | apt-get update && apt-get install -y \ 274 | jq && \ 275 | for toolset in ${BUNDLE_PATH}/*/toolset.json; do \ 276 | jq 'walk(if type == "object" and has("extraCLIOptions") then .extraCLIOptions += ["-v"] else . end)' $toolset | (sleep 1 && tee $toolset) \ 277 | done || true 278 | 279 | #################################################################################################### 280 | # Building SwiftLint by using cross-arch Swift SDK 281 | #################################################################################################### 282 | FROM swift-sdk-preparer AS cross-arch-sdk-builder 283 | RUN --mount=type=cache,target=${DOT_CACHE},sharing=locked,id=${_BUILD_CACHE_ID} \ 284 | --mount=type=cache,target=${BUILD_DIR},sharing=locked,id=${_BUILD_CACHE_ID} \ 285 | --mount=type=bind,target=${BUNDLE_PATH}/aarch64,from=swift-aarch64 \ 286 | --mount=type=bind,target=${BUNDLE_PATH}/x86_64,from=swift-x86_64 \ 287 | swift sdk list|grep "${_SDK_NAME}" && \ 288 | swift build ${SWIFT_FLAGS} ${SWIFT_FLAGS_FOR_DEBUG} || [ -n "${SLEEP}" ] 289 | 290 | FROM swift-${_TARGET_TRIPLE_ARCH} AS runtime 291 | 292 | #################################################################################################### 293 | # Building SwiftLint by using same-arch Swift SDK 294 | #################################################################################################### 295 | FROM swift-sdk-preparer AS same-arch-sdk-builder 296 | RUN --mount=type=cache,target=${DOT_CACHE},sharing=locked,id=${_BUILD_CACHE_ID} \ 297 | --mount=type=cache,target=${BUILD_DIR},sharing=locked,id=${_BUILD_CACHE_ID} \ 298 | --mount=type=bind,target=${BUNDLE_PATH}/${_TARGET_TRIPLE_ARCH},from=runtime \ 299 | swift sdk list|grep "${_SDK_NAME}" && \ 300 | swift build ${SWIFT_FLAGS} ${SWIFT_FLAGS_FOR_DEBUG} || [ -n "${SLEEP}" ] 301 | 302 | #################################################################################################### 303 | # Building SwiftLint 304 | #################################################################################################### 305 | FROM base-preparer AS no-sdk-builder 306 | RUN --mount=type=cache,target=${DOT_CACHE},sharing=locked,id=${_BUILD_CACHE_ID} \ 307 | --mount=type=cache,target=${BUILD_DIR},sharing=locked,id=${_BUILD_CACHE_ID} \ 308 | swift build ${SWIFT_FLAGS} ${SWIFT_FLAGS_FOR_DEBUG} || [ -n "${SLEEP}" ] 309 | 310 | #################################################################################################### 311 | # Select Builder and Sleep after building SwiftLint 312 | #################################################################################################### 313 | FROM ${_BUILDER_SELECTOR}-builder AS builder-selector-to-sleep 314 | RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache 315 | ARG APT_CACHE_ID=apt-${_TARGET_NAME}-${_TARGET_TRIPLE_ARCH} 316 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${APT_CACHE_ID} \ 317 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=${APT_CACHE_ID} \ 318 | --mount=type=cache,target=${DOT_CACHE},sharing=locked,id=${_BUILD_CACHE_ID} \ 319 | --mount=type=cache,target=${BUILD_DIR},sharing=locked,id=${_BUILD_CACHE_ID} \ 320 | --mount=type=bind,target=${BUNDLE_PATH}/aarch64,from=swift-aarch64 \ 321 | --mount=type=bind,target=${BUNDLE_PATH}/x86_64,from=swift-x86_64 \ 322 | pidns=$(readlink /proc/self/ns/pid|sed -E 's/pid:\[([0-9]+)\]/\1/') && \ 323 | cat < /etc/apt/apt.conf.d/keep-cache 351 | ARG _RUNTIME_NAME _TARGET_TRIPLE_ARCH 352 | ARG APT_CACHE_ID=apt-${_RUNTIME_NAME}-${_TARGET_TRIPLE_ARCH} 353 | RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${APT_CACHE_ID} \ 354 | --mount=type=cache,target=/var/lib/apt,sharing=locked,id=${APT_CACHE_ID} \ 355 | apt-get update && apt-get install -y \ 356 | libcurl4 \ 357 | libxml2 358 | COPY --link --from=builder /usr/bin/swiftlint /usr/bin/ 359 | # Copy Swift runtime libraries if not exists 360 | RUN --mount=type=bind,target=/runtime,from=runtime <<'EOT' 361 | #!/bin/bash -eu 362 | sourcekit=/usr/lib/libsourcekitdInProc.so 363 | test -f "${sourcekit}" && exit # assume that the libraries exist 364 | dependencies_txt=$(realpath $(ldd "/runtime${sourcekit}" | awk '/=>/ && $3~/\/lib\/swift/{print $3}')) 365 | dependencies=() 366 | while read -r line; do dependencies+=("$line"); done <<< "${dependencies_txt}" 367 | for dependency in "${dependencies[@]}"; do 368 | dirname=$(dirname "${dependency}") 369 | test -d "${dirname#/runtime}" || mkdir -p "${dirname#/runtime}" 370 | cp -pv "${dependency}" "${dirname#/runtime}" 371 | done 372 | cp -pv /runtime$sourcekit $(dirname $sourcekit) 373 | EOT 374 | COPY --chmod=755 <<'EOT' /usr/local/bin/swiftlint 375 | #!/bin/bash 376 | swiftlint=/usr/bin/swiftlint 377 | is_container() { [[ -f /.dockerenv ]]; } 378 | is_docker() { [[ "$(/dev/null; } 379 | is_qemu() { 380 | # Use awk instead of grep because grep may crashes with QEMU interpreter 381 | awk 'BEGIN{s=1}/qemu-(aarch64|x86_64)-static/{s=0}END{exit s}' /proc/1/maps &>/dev/null 382 | } 383 | 384 | if is_qemu; then 385 | is_container || is_docker && IGNORE_ERROR_ON_QEMU=${IGNORE_ERROR_ON_QEMU:-true} 386 | if [[ -n "$IGNORE_ERROR_ON_QEMU" ]]; then 387 | echo "Executing swiftlint with enabling timeout, because swiftlint may crashes or hangs when running with QEMU interpreter" >&2 388 | timeout --preserve-status --foreground --kill-after=310 300 $swiftlint "$@" || true 389 | else 390 | exec $swiftlint "$@" 391 | fi 392 | else 393 | exec $swiftlint "$@" 394 | fi 395 | EOT 396 | COPY --chmod=755 <<"EOT" /usr/local/bin/archive-swiftlint-runtime 397 | #!/bin/bash -eux 398 | tar czO -C / \ 399 | usr/bin/swiftlint \ 400 | usr/local/bin/swiftlint \ 401 | usr/local/bin/archive-swiftlint-runtime 402 | EOT 403 | 404 | # Print Installed SwiftLint Version 405 | RUN ["swiftlint", "version"] 406 | RUN echo "_ = 0" | exec swiftlint --use-stdin 407 | CMD ["swiftlint", "lint"] 408 | -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/aarch64-on-aarch64/swift-sdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "4.0", 3 | "targetTriples": { 4 | "aarch64-unknown-linux-gnu": { 5 | "sdkRootPath": "../aarch64", 6 | "swiftResourcesPath": "../aarch64/usr/lib/swift", 7 | "swiftStaticResourcesPath": "../aarch64/usr/lib/swift_static", 8 | "toolsetPaths": [ 9 | "toolset.json" 10 | ] 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/aarch64-on-aarch64/toolset.json: -------------------------------------------------------------------------------- 1 | { 2 | "cxxCompiler": { 3 | "extraCLIOptions": [ 4 | "-lstdc++" 5 | ] 6 | }, 7 | "librarian": { 8 | "path": "llvm-ar" 9 | }, 10 | "linker": { 11 | "path": "aarch64-linux-gnu-ld.gold", 12 | "extraCLIOptions": [ 13 | ] 14 | }, 15 | "rootPath": "../aarch64/usr/bin", 16 | "schemaVersion": "1.0", 17 | "swiftCompiler": { 18 | "extraCLIOptions": [ 19 | "-swift-version", "5", 20 | "-use-ld=gold" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/aarch64-on-x86_64/swift-sdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "4.0", 3 | "targetTriples": { 4 | "aarch64-unknown-linux-gnu": { 5 | "sdkRootPath": "../aarch64", 6 | "swiftResourcesPath": "../aarch64/usr/lib/swift", 7 | "swiftStaticResourcesPath": "../aarch64/usr/lib/swift_static", 8 | "toolsetPaths": [ 9 | "toolset.json" 10 | ] 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/aarch64-on-x86_64/toolset.json: -------------------------------------------------------------------------------- 1 | { 2 | "cxxCompiler": { 3 | "extraCLIOptions": [ 4 | "-lstdc++" 5 | ] 6 | }, 7 | "librarian": { 8 | "path": "llvm-ar" 9 | }, 10 | "linker": { 11 | "path": "aarch64-linux-gnu-ld.gold", 12 | "extraCLIOptions": [ 13 | ] 14 | }, 15 | "rootPath": "../x86_64/usr/bin", 16 | "schemaVersion": "1.0", 17 | "swiftCompiler": { 18 | "extraCLIOptions": [ 19 | "-swift-version", "5", 20 | "-use-ld=gold" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "artifacts": { 3 | "aarch64-on-aarch64": { 4 | "type": "swiftSDK", 5 | "variants": [ 6 | { 7 | "path": "aarch64-on-aarch64", 8 | "supportedTriples": [ 9 | "aarch64-unknown-linux-gnu" 10 | ] 11 | } 12 | ], 13 | "version": "0.0.1" 14 | }, 15 | "aarch64-on-x86_64": { 16 | "type": "swiftSDK", 17 | "variants": [ 18 | { 19 | "path": "aarch64-on-x86_64", 20 | "supportedTriples": [ 21 | "x86_64-unknown-linux-gnu" 22 | ] 23 | } 24 | ], 25 | "version": "0.0.1" 26 | }, 27 | "x86_64-on-aarch64": { 28 | "type": "swiftSDK", 29 | "variants": [ 30 | { 31 | "path": "x86_64-on-aarch64", 32 | "supportedTriples": [ 33 | "aarch64-unknown-linux-gnu" 34 | ] 35 | } 36 | ], 37 | "version": "0.0.1" 38 | }, 39 | "x86_64-on-x86_64": { 40 | "type": "swiftSDK", 41 | "variants": [ 42 | { 43 | "path": "x86_64-on-x86_64", 44 | "supportedTriples": [ 45 | "x86_64-unknown-linux-gnu" 46 | ] 47 | } 48 | ], 49 | "version": "0.0.1" 50 | } 51 | }, 52 | "schemaVersion": "1.0" 53 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/x86_64-on-aarch64/swift-sdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "4.0", 3 | "targetTriples": { 4 | "x86_64-unknown-linux-gnu": { 5 | "sdkRootPath": "../x86_64", 6 | "swiftResourcesPath": "../x86_64/usr/lib/swift", 7 | "swiftStaticResourcesPath": "../x86_64/usr/lib/swift_static", 8 | "toolsetPaths": [ 9 | "toolset.json" 10 | ] 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/x86_64-on-aarch64/toolset.json: -------------------------------------------------------------------------------- 1 | { 2 | "cxxCompiler": { 3 | "extraCLIOptions": [ 4 | "-lstdc++" 5 | ] 6 | }, 7 | "librarian": { 8 | "path": "llvm-ar" 9 | }, 10 | "linker": { 11 | "path": "x86_64-linux-gnu-ld.gold", 12 | "extraCLIOptions": [ 13 | ] 14 | }, 15 | "rootPath": "../aarch64/usr/bin", 16 | "schemaVersion": "1.0", 17 | "swiftCompiler": { 18 | "extraCLIOptions": [ 19 | "-swift-version", "5", 20 | "-use-ld=gold" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/x86_64-on-x86_64/swift-sdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": "4.0", 3 | "targetTriples": { 4 | "x86_64-unknown-linux-gnu": { 5 | "sdkRootPath": "../x86_64", 6 | "swiftResourcesPath": "../x86_64/usr/lib/swift", 7 | "swiftStaticResourcesPath": "../x86_64/usr/lib/swift_static", 8 | "toolsetPaths": [ 9 | "toolset.json" 10 | ] 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /builder/swift-sdks.artifactbundle/x86_64-on-x86_64/toolset.json: -------------------------------------------------------------------------------- 1 | { 2 | "cxxCompiler": { 3 | "extraCLIOptions": [ 4 | "-lstdc++" 5 | ] 6 | }, 7 | "librarian": { 8 | "path": "llvm-ar" 9 | }, 10 | "linker": { 11 | "path": "x86_64-linux-gnu-ld.gold", 12 | "extraCLIOptions": [ 13 | ] 14 | }, 15 | "rootPath": "../x86_64/usr/bin", 16 | "schemaVersion": "1.0", 17 | "swiftCompiler": { 18 | "extraCLIOptions": [ 19 | "-swift-version", "5", 20 | "-use-ld=gold" 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /copier/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | # runtime image 4 | ARG TARGET_IMAGE=swift 5 | ARG RUNTIME_IMAGE=${TARGET_IMAGE} 6 | 7 | # Decide _TARGET_TRIPLE_ARCH from TARGETARCH 8 | ARG _TARGET_TRIPLE_ARCH=${TARGETARCH} 9 | ARG _TARGET_TRIPLE_ARCH=${_TARGET_TRIPLE_ARCH/*arm64/aarch64} 10 | ARG _TARGET_TRIPLE_ARCH=${_TARGET_TRIPLE_ARCH/*amd64/x86_64} 11 | ARG _TARGET_TRIPLE_ARCH=${_TARGET_TRIPLE_ARCH/linux*/} 12 | 13 | FROM ${TARGET_IMAGE} AS runtime 14 | 15 | FROM ${RUNTIME_IMAGE} AS final 16 | LABEL maintainer="Norio Nomura " 17 | RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /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 | --------------------------------------------------------------------------------