Skip to content

Set up SwiftLint as a standalone build plugin#23996

Merged
mokagio merged 8 commits intotrunkfrom
mokagio/swiftlint-via-isolated-plugin
Feb 18, 2025
Merged

Set up SwiftLint as a standalone build plugin#23996
mokagio merged 8 commits intotrunkfrom
mokagio/swiftlint-via-isolated-plugin

Conversation

@mokagio
Copy link
Contributor

@mokagio mokagio commented Jan 21, 2025

#23958 removes CocoaPods from the project setup, but with SwiftLint also goes away.

This PR re-introduces SwiftLint, fetching it using the SwiftPM plugin repo but then calling the binary directly via the existing SwiftLint aggregate target (which calls rake lint under the hood.

I considered using the plugin setup, see #23990, but didn't go ahead with it because:

  • It requires integrating in every target
  • It does not seem to care about our configuration
  • It requires extract flags for permissions when running in CI and will prompt the user on first run locally
  • The setup does not lend itself to having a single source of truth for the SwiftLint version to use, which is a requirement for our CI linter to run—and I strongly advice keeping the CI linter setup as it is
  • In my few minutes of tinkering with it, Xcode crashed at least 4 times (see example in SwiftLint Build Tool Plugin example #23990 description)
  • This is a bit of an argument from authority, which is why I'm leaving it last and using it more as a reinforcement of my conclusion than an explanation, but even the original SwiftLint author recommend against using the plugin

For reference, this setup is inspired by SwiftFormat.

I considered fetching SwiftLint directly instead of the plugin, but doing so would have required compiling SwiftLint from source to run it, which was very time consuming.

Finally, it crossed my mind to keep the old CocoaPods setup for SwiftLint. I started going down that path in #23998 but stopped once I noticed that the performance using the setup in this PR were comparable to those on trunk, see #23999

Given that removing CocoaPods whether to build the app or for tooling, brings us closer to our goal of no longer depending on Ruby for product-development tasks, I'd rather stick with this Swift-only approach.

Note

I'm having issues archiving the app via Fastlane, even though vanilla xcodebuild and Xcode work fine. I'm investigating...

error: module 'WordPressSharedObjC' in AST file 
'/Users/gio/Developer/a8c/wpios/DerivedData/ModuleCache.noindex/EQUUY9BHSJ5N/WordPressSharedObjC-5G93B85NZ09I.pcm'
(imported by AST file '/Users/gio/Developer/a8c/wpios/DerivedData/WordPress/Build/Intermediates.noindex/ArchiveIntermediates/WordPress Alpha/PrecompiledHeaders/WordPress-Bridging-Header-swift_1L0UBHDEION2G-clang_EQUUY9BHSJ5N.pch')
is not defined in any loaded module map file;
maybe you need to load /Users/gio/Developer/a8c/wpios/DerivedData/WordPress/Build/Intermediates.noindex/ArchiveIntermediates/WordPress Alpha/IntermediateBuildFilesPath/GeneratedModuleMaps-iphoneos/WordPressSharedObjC.modulemap'?

Apart from being unsure about the error itself, I don't understand is how the changes in this PR might be affecting the build that way...

Updated I haven't fixed the issue but I have a workaround that I like and that I think we should consider in order to merge this PR and then move forward with #23958

The TL;DR is that the error occurs only when building builds with configuration Release or Release-Alpha, so I told the script that runs SwiftLint to only run on Debug builds. We have CI covering us when building a different configuration because it runs the standalone linter. In fact, I also disabled the SwiftLint build phase in CI, to save time because of that.

Regression Notes

  1. Potential unintended areas of impact – N.A.
  2. What I did to test those areas of impact (or what existing automated tests I relied on) – N.A.
  3. What automated tests I added (or what prevented me from doing so) – N.A.

PR submission checklist:

  • I have completed the Regression Notes.
  • I have considered adding unit tests for my changes. N.A.
  • I have considered adding accessibility improvements for my changes. N.A.
  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary. N.A.

UI changes testing checklist: Not a UI PR.

@mokagio mokagio changed the base branch from trunk to mokagio/remove-cocoapods-christmast-branch January 21, 2025 09:08
@wpmobilebot
Copy link
Contributor

wpmobilebot commented Jan 21, 2025

Jetpack Alpha📲 You can test the changes from this Pull Request in Jetpack Alpha by scanning the QR code below to install the corresponding build.
App NameJetpack Alpha Jetpack Alpha
ConfigurationRelease-Alpha
Build Numberpr23996-5ea934a
Version25.7.1
Bundle IDcom.jetpack.alpha
Commit5ea934a
App Center Buildjetpack-installable-builds #10536
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Jan 21, 2025

WordPress Alpha📲 You can test the changes from this Pull Request in WordPress Alpha by scanning the QR code below to install the corresponding build.
App NameWordPress Alpha WordPress Alpha
ConfigurationRelease-Alpha
Build Numberpr23996-5ea934a
Version25.7.1
Bundle IDorg.wordpress.alpha
Commit5ea934a
App Center BuildWPiOS - One-Offs #11504
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@mokagio mokagio mentioned this pull request Jan 21, 2025
14 tasks
@mokagio mokagio force-pushed the mokagio/swiftlint-via-isolated-plugin branch from 8df602d to f692687 Compare January 21, 2025 20:46
let animatedImage = image as? AnimatedImage,
animatedImage.gifData != nil
{
animatedImage.gifData != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving up from version 0.54.0 brought up this and other opening_brace violations.

Might be related to the rule having been rewritten in version 0.55.0 and then updated in version 0.57.0.

@@ -1,10 +1,11 @@
swiftlint_version: 0.54.0
swiftlint_version: 0.58.2
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot use 0.54.0 because it's not available as a built tool plugin, see https://github.com/SimplyDanny/SwiftLintPlugins/releases

Given that, it makes sense to use the latest available version. But even if we didn't want to:

  • 0.58.0 and 0.58.1 have a bug where the Docker image reads the wrong version, so we cannot use them
  • 0.55.0 does not have the --working-directory option which we need

@mokagio mokagio force-pushed the mokagio/swiftlint-via-isolated-plugin branch from af75c45 to db78e12 Compare January 23, 2025 00:15
@mokagio mokagio marked this pull request as ready for review January 23, 2025 00:54
@mokagio mokagio added the Tooling Build, Release, and Validation Tools label Jan 23, 2025
@mokagio mokagio added this to the Pending milestone Jan 23, 2025
@mokagio mokagio requested review from a team, crazytonyli and kean January 23, 2025 00:58
Copy link
Contributor

@kean kean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit of an argument from authority, which is why I'm leaving it last and using it more as a reinforcement of my conclusion than an explanation, but realm/SwiftLint#5207 (comment)

I concur. It should be used only when the code requires a tool to compile – mainly code generators.

@@ -0,0 +1 @@
.build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add it to the .gitignore file in the root directory.

name: "BuildTools",
platforms: [.macOS(.v10_13)],
dependencies: [
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", exact: loadSwiftLintVersion()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the version numbers have to be in .swiftlint.yml? Are there any other roadblocks for simply defining the version here in the package:

.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", exact: "0.58.2"),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.swiftlint.yml needs to specify the SwiftLint version the configuration expects

https://github.com/Automattic/a8c-ci-toolkit-buildkite-plugin/blob/29064ab1e6e49135f9700d86b7b3279081b9ebc9/bin/run_swiftlint#L23-L27

We don't have to read the version from there here, but I find it nice to have a single source of truth.

We could duplicate the value here, but we might run into some annoying issues if the version defined here diverges from the one in the config so that we end up with CI running a different version than local and giving different feedback.

@mokagio mokagio force-pushed the mokagio/remove-cocoapods-christmast-branch branch from 5189e4b to d7d0010 Compare February 5, 2025 05:47
Base automatically changed from mokagio/remove-cocoapods-christmast-branch to trunk February 11, 2025 03:38
@mokagio mokagio force-pushed the mokagio/swiftlint-via-isolated-plugin branch from 8479673 to 5ea934a Compare February 18, 2025 03:57
@mokagio mokagio enabled auto-merge February 18, 2025 03:58
@mokagio mokagio added this pull request to the merge queue Feb 18, 2025
@mokagio
Copy link
Contributor Author

mokagio commented Feb 18, 2025

I thought I'd merged this already 😳

Apologies for letting this sit in the limbo for so long...

Merged via the queue into trunk with commit c252626 Feb 18, 2025
24 of 25 checks passed
@mokagio mokagio deleted the mokagio/swiftlint-via-isolated-plugin branch February 18, 2025 05:01
Comment on lines +12 to +18
# For some reason, running when trying to archive, via CLI, results in a compilation failure.
#
# fatal error: module 'WordPressSharedObjC' in AST file '/path/to/DerivedData/ModuleCache.noindex/EQUUY9BHSJ5N/WordPressSharedObjC-5G93B85NZ09I.pcm'
# (imported by AST file '/Users/gio/Developer/a8c/wpios/DerivedData/WordPress/Build/Intermediates.noindex/ArchiveIntermediates/WordPress Alpha/PrecompiledHeaders/WordPress-Bridging-Header-swift_1L0UBHDEION2G-clang_EQUUY9BHSJ5N.pch')
# is not defined in any loaded module map file;
# maybe you need to load '/Users/gio/Developer/a8c/wpios/DerivedData/WordPress/Build/Intermediates.noindex/ArchiveIntermediates/WordPress Alpha/IntermediateBuildFilesPath/GeneratedModuleMaps-iphoneos/WordPressSharedObjC.modulemap'?
if [ "${CONFIGURATION}" != "Debug" ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: if the error is really related to archiving vs just building, as opposed to debug vs release, I think you could have used the ${ACTION} env var to check for build vs archive? 🤷

mokagio added a commit that referenced this pull request Feb 19, 2025
Co-authored-by: Olivier Halligon <olivier.halligon@automattic.com>

Follows up on
#23996 (comment)

Makes the logic more precise, given the error occurs when archiving.
mokagio added a commit that referenced this pull request Feb 19, 2025
Co-authored-by: Olivier Halligon <olivier.halligon@automattic.com>

Follows up on
#23996 (comment)

Makes the logic more precise, given the error occurs when archiving.
github-merge-queue bot pushed a commit that referenced this pull request Feb 19, 2025
* Bypass SwiftLint using `ACTION` instead of `CONFIGURATION`

Co-authored-by: Olivier Halligon <olivier.halligon@automattic.com>

Follows up on
#23996 (comment)

Makes the logic more precise, given the error occurs when archiving.

* Add note about inconsistent failure when archiving locally
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Tooling Build, Release, and Validation Tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants