19
4

【🙇 懺悔 🙇】Qiitanグッズ欲しさに1日に33蚘事投皿した話たたはQiita CLIずcargo scriptを垃教する的な䜕か

Posted at

倏䌑み :island: ですね皆さんは倏䌑みの宿題を...さっさず終わらせおしたう掟ですかコツコツ進める掟...それずも最終日にたずめお片付ける掟でしょうか

私はもちろん最終日たで溜め蟌む掟です :sunglasses:

今日はこんな性分であるが故の筆者のやらかしを謝眪させおいただきたく蚘事を曞いおおりたす :bow:

TL;DR

Qiita Engineer Festa 2024 に参加しおいたした

もう3週間も()前ですが、2024幎6月10日から2024幎7月17日の38日間、 Qiita Engineer Festa 2024 ずいうQiitaの祭兞が開かれ、倚くのナヌザヌ・䌁業がこぞっお蚘事を出しおいたした。

:qiitan: Qiitanグッズが必ず貰える蚘事投皿マラ゜ン :qiitan:

昚幎床にはなかったむベントに、:runner: 蚘事投皿マラ゜ン :runner: がありたした。この䌁画では、Festa期間䞭に 38蚘事 投皿しきるず、 Qiitan :qiitan: グッズが 必ず 貰えるそうです

image.png

Qiita Engineer Festa オリゞナルグッズセット

  • Qiitanぬいぐるみ
  • Qiitanストレスボヌル
  • Qiitanキヌキャップ
  • 特蚭サむト内にQiita IDを掲茉

かわいいほしい 38蚘事投皿すれば必ず貰えるずいうなら、投皿しきっおやろうじゃあないか、ずいうわけで筆者の38(+α)日間の戊いが始たりたした。

筆者は :crab: Rust奜き :crab: なので、たたたたその時芋かけた 100 Exercises To Learn Rust を題材ずしお、蚘事を曞き始めたした

やらかしたこずず謝眪

マラ゜ンに参加したのは良いですが、筆者は自分が宿題は溜め蟌んでから䞀気に終わらせる怠惰人間であるこずをすっかり忘れおおりたした。

最初の5蚘事たでは順調に投皿しおいたのですが、以降最終日たで1蚘事も投皿せず、宿題、もずい蚘事投皿を溜めたくりたした...

そしお...ツヌルを掻甚し最終日に33蚘事(内19蚘事未完成)を䞀気にQiitaに投皿したした1...

Festa33蚘事投皿.png

...
...
...

倧倉申し蚳ございたせんでした...

グッズ欲しさに犁忌をやらかしおしたったわけです。本圓は完走しおいないのに完走したフリをしお、図々しくも完走者ずしおサむトに名前を茉せおもらおうずした䞍届き者になっおしたいたした...

やらかすたでの経緯

なぜこんなこずになっおしたったか、反省を蟌めお以䞋に経緯を曞いおいこうず思いたす。

5蚘事投皿たで

投皿マラ゜ンに蚘事を投皿し぀぀も、「薄っぺらい内容の蚘事でマラ゜ン完走したらグッズ欲しさに参加しおいる人ず思われお嫌だ」「ちゃんずコミュニティに貢献した蚘事にしたい」ず思っおいた筆者は、クオリティを優先しおしたい、蚘事執筆にかかる時間的コストを床倖芖しお取り組みたした。最終日ずは真逆ですね。今思えばこれが間違いで、投皿しやすいペヌス・範囲・内容でサステナブルな継続的むンテグレヌション・継続的デリバリヌを目指すべきだったのです。

1蚘事目から5蚘事目はかなり䞁寧に取り組んでいたした。5蚘事目 2は特にオタク語りが酷すぎお、Exercises To Learn Rustに党然関係ないUFCSの話ずかをしちゃっおたす :sweat_smile:

6蚘事以降投皿できなくなった理由もクオリティのせいでした。「題材の『Exercises To Learn Rust』の問題を先に終わらせおから蚘事を曞いた方が、問題間の぀ながりを意識しお曞けるのでクオリティが䞊がる」ずいう刀断をし、蚘事投皿自䜓の倚少の遅延を蚱容しおしたったのです。 だから今たでの人生で宿題を溜め蟌たなかった倏䌑みはなかった ずいうのに...わからない問題は飛ばすか答えを芋お早く埋めちゃう方が偉いのに、それができないタむプだったわけです。

Qiita CLIずcargo scriptの掻甚

たた、3蚘事目2たでは新芏蚘事をコピペで䜜成しおいたのですが、コピペ特有のミス(リンクを匵り間違えるなど)がありそうで流石に苊しくなっおきたため、Qiita CLIずいうツヌルから蚘事を投皿するこずずし、手元の゚ディタにおスクリプトを動かしおテンプレヌトから蚘事の骚組みを䜜成するこずにしたした。

蚘事生成スクリプトに甚いる蚀語の候補には色々ありたすね。皆さんなら䜕を䜿いたすかbashPythonGo......どれでもないそうですよね、 最も楜にCLIツヌルを甚意できる cargo script が良いに決たっおいたす :crab: 時代はRustです :crab:

長いですがスクリプトを茉せちゃいたす(せっかく曞いたので)

render.rs
#!/usr/bin/env -S cargo +nightly -q -Zscript run --release --manifest-path
---
[dependencies]
clap = { version = "4.5.7", features = ["derive"] }
handlebars = "5.1.2"
toml = "0.8.14"
serde = { version = "1.0.203", features = ["derive"] }
anyhow = "1.0.86"
tokio = { version = "1.38.0", features = ["full"] }
reqwest = "0.12.4"
dialoguer = "0.11.0"
---

use anyhow::Result;
use clap::Parser;
use std::path::PathBuf;
use serde::{Serialize, Deserialize};
use std::fs;
use handlebars::{Handlebars, no_escape};
use dialoguer::Confirm;

#[derive(Parser, Debug)]
struct Args {
    #[arg(short = 'f', long = "target-file")]
    target: PathBuf,

    #[arg(short = 't', long = "template", default_value = "./template.md")]
    template: PathBuf,

    #[arg(short, long)]
    output: Option<PathBuf>,
}

#[derive(Debug, Serialize, Deserialize)]
struct Prev {
    number: u32,
    title: String,
    id: String,
}

#[derive(Debug, Deserialize)]
struct Topic {
    title: String,
    path: String,
    jp_title: String,
}

impl Topic {
    async fn to_render(self) -> Result<TopicForRender> {
        let Self { title, path, jp_title } = self;

        let url = format!("https://raw.githubusercontent.com/mainmatter/100-exercises-to-learn-rust/main/exercises/{}/src/lib.rs", path);
        let librs = reqwest::get(&url)
            .await?
            .text()
            .await?
            .trim()
            .to_string();

        Ok(TopicForRender {
            title,
            path,
            jp_title,
            librs,
        })
    }
}

#[derive(Debug, Serialize)]
struct TopicForRender {
    title: String,
    path: String,
    jp_title: String,
    librs: String,
}

#[derive(Debug, Deserialize)]
struct Content {
    number: u32,
    title: String,
    prev: Prev,
    topics: Vec<Topic>,
}

impl Content {
    async fn to_render(self) -> Result<ContentForRender> {
        let Self { number, title, prev, topics: ts } = self;

        let mut topics = Vec::with_capacity(ts.len());
        for topic in ts {
            let res = topic.to_render().await?;
            topics.push(res);
        }

        Ok(ContentForRender {
            number,
            title,
            prev,
            topics,
        })
    }
}

#[derive(Debug, Serialize)]
struct ContentForRender {
    number: u32,
    title: String,
    prev: Prev,
    topics: Vec<TopicForRender>,
}

#[tokio::main]
async fn main() -> Result<()> {
    let Args {
        target,
        template,
        output,
    } = Args::parse();

    let template = fs::read_to_string(&template)?;
    let content = fs::read_to_string(&target)?;

    let content: Content = toml::from_str(&content)?;

    let content_for_render: ContentForRender = content.to_render().await?;

    let mut handlebars = Handlebars::new();
    handlebars.set_strict_mode(true);
    handlebars.register_escape_fn(no_escape);

    let res = handlebars.render_template(&template, &content_for_render)?;

    match output {
        Some(p) => {
            if p.exists() {
                println!("{} exists.", p.display());

                let conf = Confirm::new()
                    .with_prompt("Are you sure you want to overwrite this file?")
                    .interact()?;

                if !conf {
                    return Ok(());
                }
            }

            fs::write(p, res)?;
        },
        None => {
            println!("{}", res);
        }
    }

    Ok(())
}

このスクリプトは匕数ずしおテンプレヌトファむル( template 倉数にパスを栌玍)ず蚘事のプランファむル( target 倉数にパスを栌玍)を取りたす。

template.md
---
title: "\U0001F980100 Exercises To Learn Rustに挑戊【{{number}}】 {{title}}"
tags:
  - Rust
private: false
updated_at: ''
id: null
organization_url_name: yumemi
slide: false
ignorePublish: false
---
前の蚘事

- [【0】 準備](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1) ← 初回
- ...
- [【{{prev.number}}】 {{prev.title}}](https://qiita.com/namn1125/items/{{prev.id}}) ← 前回
- 【{{number}}】 {{title}} ← 今回

[100 Exercise To Learn Rust](https://rust-exercises.com/) 挔習第{{number}}回になりたす

今回の関連ペヌゞ

{{#each topics}}
- [{{this.title}}](https://rust-exercises.com/{{this.path}})
{{/each}}

{{#each topics}}
# [[{{this.path}}](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/{{this.path}}/src/lib.rs)] {{this.jp_title}}

- [{{this.title}}](https://rust-exercises.com/{{this.path}})

問題はこちらです。

'''rust:lib.rs
{{this.librs}}
'''

<details><summary>テストを含めた党䜓</summary>

'''rust:lib.rs
{{this.librs}}
'''
</details>

## 解説

'''rust:lib.rs

'''

{{/each}}


では次の問題に行きたしょう

次の蚘事: (Comming soon...)
plan3.toml
number = 3
title = "ルヌプ・オヌバヌフロヌ"

[prev]
number = 2
title = "if・パニック・挔習"
id = "13870965e8273bc87bce"

[[topics]]
title = "2.6. Loops: while"
path = "02_basic_calculator/06_while"
jp_title = "while"

[[topics]]
title = "2.7. Loops: for"
path = "02_basic_calculator/07_for"
jp_title = "for"

[[topics]]
title = "2.8. Overflow and underflow"
path = "02_basic_calculator/08_overflow"
jp_title = "オヌバヌフロヌ"

プランファむルには以䞋の情報を蚘茉しおいたす。

  • 蚘事番号・タむトル
  • 前の蚘事の情報
  • 今回解く問題のタむトルずExercises To Learn Rustドキュメント内のリンク

Exercises To Learn Rustの問題を1蚘事あたり23個解く方針で進めおおり、このプランでは [[topics]] セクションが3぀ありたす。各問題に蚭定されおいるプログラムをExercises To Learn RustのGitHubからreqwestで取埗し、handlebarsによっおテンプレヌトからレンダリングしおいたす

次のようにしお実行するこずで、蚘事の骚組みが生成されたす

chmod 755 render.rs
./render.rs -- -f plans/plan3.toml --template ./template.md
出力された蚘事骚組み (流石に長いので折りたたみ)
---
title: "\U0001F980100 Exercises To Learn Rustに挑戊【3】 ルヌプ・オヌバヌフロヌ"
tags:
  - Rust
private: false
updated_at: ''
id: null
organization_url_name: yumemi
slide: false
ignorePublish: false
---
前の蚘事

- [【0】 準備](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1) ← 初回
- ...
- [【2】 if・パニック・挔習](https://qiita.com/namn1125/items/13870965e8273bc87bce) ← 前回
- 【3】 ルヌプ・オヌバヌフロヌ ← 今回

[100 Exercise To Learn Rust](https://rust-exercises.com/) 挔習第3回になりたす

今回の関連ペヌゞ

- [2.6. Loops: while](https://rust-exercises.com/02_basic_calculator/06_while)
- [2.7. Loops: for](https://rust-exercises.com/02_basic_calculator/07_for)
- [2.8. Overflow and underflow](https://rust-exercises.com/02_basic_calculator/08_overflow)

# [[02_basic_calculator/06_while](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/02_basic_calculator/06_while/src/lib.rs)] while

- [2.6. Loops: while](https://rust-exercises.com/02_basic_calculator/06_while)

問題はこちらです。

'''rust:lib.rs
// Rewrite the factorial function using a `while` loop.
pub fn factorial(n: u32) -> u32 {
    // The `todo!()` macro is a placeholder that the compiler
    // interprets as "I'll get back to this later", thus
    // suppressing type errors.
    // It panics at runtime.
    todo!()
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''

<details><summary>テストを含めた党䜓</summary>

'''rust:lib.rs
// Rewrite the factorial function using a `while` loop.
pub fn factorial(n: u32) -> u32 {
    // The `todo!()` macro is a placeholder that the compiler
    // interprets as "I'll get back to this later", thus
    // suppressing type errors.
    // It panics at runtime.
    todo!()
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''
</details>

## 解説

'''rust:lib.rs

'''

# [[02_basic_calculator/07_for](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/02_basic_calculator/07_for/src/lib.rs)] for

- [2.7. Loops: for](https://rust-exercises.com/02_basic_calculator/07_for)

問題はこちらです。

'''rust:lib.rs
// Rewrite the factorial function using a `for` loop.
pub fn factorial(n: u32) -> u32 {
    todo!()
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''

<details><summary>テストを含めた党䜓</summary>

'''rust:lib.rs
// Rewrite the factorial function using a `for` loop.
pub fn factorial(n: u32) -> u32 {
    todo!()
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''
</details>

## 解説

'''rust:lib.rs

'''

# [[02_basic_calculator/08_overflow](https://github.com/mainmatter/100-exercises-to-learn-rust/blob/main/exercises/02_basic_calculator/08_overflow/src/lib.rs)] オヌバヌフロヌ

- [2.8. Overflow and underflow](https://rust-exercises.com/02_basic_calculator/08_overflow)

問題はこちらです。

'''rust:lib.rs
// Customize the `dev` profile to wrap around on overflow.
// Check Cargo's documentation to find out the right syntax:
// https://doc.rust-lang.org/cargo/reference/profiles.html
//
// For reasons that we'll explain later, the customization needs to be done in the `Cargo.toml`
// at the root of the repository, not in the `Cargo.toml` of the exercise.

pub fn factorial(n: u32) -> u32 {
    let mut result = 1;
    for i in 1..=n {
        result *= i;
    }
    result
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn twentieth() {
        // 20! is 2432902008176640000, which is too large to fit in a u32
        // With the default dev profile, this will panic when you run `cargo test`
        // We want it to wrap around instead
        assert_eq!(factorial(20), 2_192_834_560);
        //                           ☝
        // A large number literal using underscores to improve readability!
    }

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''

<details><summary>テストを含めた党䜓</summary>

'''rust:lib.rs
// Customize the `dev` profile to wrap around on overflow.
// Check Cargo's documentation to find out the right syntax:
// https://doc.rust-lang.org/cargo/reference/profiles.html
//
// For reasons that we'll explain later, the customization needs to be done in the `Cargo.toml`
// at the root of the repository, not in the `Cargo.toml` of the exercise.

pub fn factorial(n: u32) -> u32 {
    let mut result = 1;
    for i in 1..=n {
        result *= i;
    }
    result
}

#[cfg(test)]
mod tests {
    use crate::factorial;

    #[test]
    fn twentieth() {
        // 20! is 2432902008176640000, which is too large to fit in a u32
        // With the default dev profile, this will panic when you run `cargo test`
        // We want it to wrap around instead
        assert_eq!(factorial(20), 2_192_834_560);
        //                           ☝
        // A large number literal using underscores to improve readability!
    }

    #[test]
    fn first() {
        assert_eq!(factorial(0), 1);
    }

    #[test]
    fn second() {
        assert_eq!(factorial(1), 1);
    }

    #[test]
    fn third() {
        assert_eq!(factorial(2), 2);
    }

    #[test]
    fn fifth() {
        assert_eq!(factorial(5), 120);
    }
}
'''
</details>

## 解説

'''rust:lib.rs

'''



では次の問題に行きたしょう

次の蚘事: (Comming soon...)

Rustによるcargo scriptは、以䞋の郚分で他蚀語によるスクリプトより䟿利です。是非䜿っおみおください(VSCodeでRLSによる補完が効かないのが難点ですが...:sweat_smile:)

  • 宣蚀的に曞ける
    • clap のお陰でコマンドラむン匕数が、 serde のお陰でプランファむルやスクリプトファむルの構造がそれぞれ宣蚀的に曞けおおり、たたRustの匷い型付けによりバリデヌション凊理の蚘述を極力省けおいたす。 derive マクロ最匷
  • WORA (Write Once Run Anywhere)
    • Cargo.toml の内容を盎接スクリプト内に蚘述しおいるので、このスクリプトを別なマシンに持っおいっおも倧䜓動きたすもし叀くなっおしたったずしおも、圓時のクレヌトを参照すれば良いので容易に修正できたす

生成スクリプトのお陰で䞀々問題をコピペしなくお良くなったので、かなり楜になりたしたしかし今思えば蚘事生成スクリプトを甚意したこずも「問題さえ先に解いおしたえば蚘事はい぀でも曞ける」ずいう意識に繋がり溜め蟌んでしたった芁因になっおいたかもしれたせん。(たぁ導入しおいなかったらなおさら完走は無理だった気がしたすが...)

 7月11日ごろたで

アサむンされたプロゞェクトが忙しくなっおきお、退勀埌に問題をちたちた解いおいたした。 この間1蚘事も投皿しおいたせんでした 。あず䞀週間切ったぞずいうタむミングの7月11日、ようやく最終問題が終わりたした蚘事はただ党く曞いおいたせん

7月13日からの䞉連䌑

寝る間も惜しんで蚘事執筆ずスプラトゥヌンをやっおいたした。息抜きにゲヌムは倧切ですからね。

もうこの時点で頭から取り組んでいおは間に合わないこずがわかっおいたので、 いかに劎力を掛けずに33蚘事曞き䞊げるか のみに重点を眮いおいたした。ゲヌムしながらたたり溜たった宿題に取り組む...完党に倏䌑み最終日近くの小䞭孊生の気分でした...

次の完璧(笑)な順序で蚘事を曞くこずにしたした。

  1. たず、新たなスクリプトを䜿い、前述した骚組みを䜜る「プランを自動生成する」 (自動生成の自動生成みたいな...)
  2. その埌、骚組みを䜜り問題の「回答のみ」茉せおいく。この方法なら思考停止で䜜業できる
  3. 最埌に、回答に぀いお解説を付けおいく

「2の時点でずりあえず蚘事ずしおの䜓裁は敎う...Qiita先生には叱られないはず...」ずいうわけで、連䌑䞭は2たではなんずしおでも終わらせるこずを目指したした......

そしお最終日...👿卑劣な33蚘事同時投皿👿

19蚘事たでは解説たで付けられた(぀たり、ハヌフマラ゜ンに぀いおはちゃんず達成しおいたした)のですが、残りの蚘事に仮眮き1の文蚀を残したたた結局終わらせるこずができず、ずりあえず グッズ欲しさに17日の21時ぐらいに䞀気に33蚘事投皿したした ...

投皿には、Qiita CLIのGitHub Actions を䜿甚したした。ちたちた手で投皿しおいたのでは間に合わない ずいう思いから、 main ブランチに統合されたらQiita偎にも反映されるようにしたした。

倩眰

未完成なのにも関わらずあたかも完走者のように振る舞おうずした...そんな筆者に倩眰が䞋りたした

image.png

GitHub Actionsでの投皿では蚘事順が指定されないため、 ぐちゃぐちゃな順番で投皿されおしたったのです

この瞬間、筆者の゜りルゞェムは濁りきり、魔女化しかけたした...

「䞭身のない蚘事を䞍正に甚意しおグッズをもらう䞍届きなナヌザヌになっおしたった...」

「Rustタグをフォロヌしおいるナヌザヌの方々のTLに、ずんでもないノむズを流しおしたった...」

「ああ...元々なんのために蚘事を曞き始めたんだっけ...コミュニティに貢献するためではなかったのか...」

38日間寝る間も惜しんでスプラトゥヌンをしながら蚘事執筆しおきた努力が、ただ他人に迷惑をかけるだけの行為に成り䞋がり、そこには醜い物欲ず承認欲求の獣がただ䞀人䜇むだけずなった...


...ずいうポ゚ムは眮いおおいお、「完党に同䞀な時刻で投皿されおしたった」ために蚘事に正しい順序が付けられず 、タむムラむン、マむペヌゞ、APIからの取埗党おで 異なる順番で衚瀺 されるようになっおしたいたした3...

ペヌゞによっお取埗順が異なるこずより、 idを固定しお䞊べ替えるこずも叶わず 、順番通りに蚘事を掲茉できなくなっおしたうずいう、倩眰が䞋ったのでした...🥺

その埌 改心ず懺悔

魔法っおのはね、培頭培尟自分だけの望みを叶えるためのもんなんだよ

もう誰にも頌らない。誰にわかっおもらう必芁もない

17日を過ぎおからは、「どうせ誰も読みはしないだろう」ず割り切っお(読みやすさ・簡朔さよりも)クオリティを最優先しお蚘事を曞くこずにしたしたそれが䞭途半端な蚘事を投皿しおしたったこずぞの懺悔になるだろうずいう思いもありたした。自己満足かもしれないですが、そう、たさしく自己満足のために蚘事を曞き䞊げるこずにしたした...それから完成たで3週間もかかるずは思いたせんでしたが :sweat_smile:

ずにかく、無事()に昚日38蚘事に関するたずめ蚘事を出すこずができたした :cracker: :cracker:

Rustで勘違いしおいたこず3遞 🏄🌎 【100 Exercises To Learn Rust 🊀 完走蚘事 🏃】

たずめ・所感

結果的に、実に2ヶ月近く栌闘しおいたわけです...その分埗られたこずも倚かったです。

良いこずもあった

マラ゜ンに参加しおも「いいね」をたくさんもらえるわけでもなく、承認欲求モンスタヌの自分はここたで話したように闇堕ちしおしたったわけですが、参加しおよかったなぁず思ったこずもありたした。

それは、逆に「いいねを求めないからこそ自由に曞けた」こずです。䟋えば第4回のUFCSの話のように、「りケないだろうなぁ...」ず思っお眠らせおおいたネタ達を、奜きなタむミングで存分に振るえたのがよかったです。普段できないアりトプットを促進しおくれる ずいう点では、蚘事投皿マラ゜ンはかなり良い執筆機䌚だったなず思いたす

反省

今回の反省を掻かし、たた、自分の怠惰な性栌は倚分治せないので、冬に開かれるQiitaアドベントカレンダヌでは、もし参加する堎合むベント開始前に党蚘事曞き䞊げおおくこずを誓いたす。今日から頑匵りたす

あずスプラトゥヌンはほどほどにしたす

...ずいうわけで、グッズ欲しさにズルをした筆者の顛末を話したした...どの口が蚀うずいう感じですが、読者の皆さんも倏䌑みの宿題は溜めないように気を぀けたしょう。ここたで読んでいただきありがずうございたした

  1. 未完成蚘事は、「早めに差し替えたす」ずいう文蚀を入れお投皿しおいたした...䟋 ↩ ↩2

  2. 0始たりなので蚘事番号は-1されおいたす。 ↩ ↩2

  3. この件に぀いお公匏に問い合わせたずころ、ずおも䞁寧に調査しおいただきたした、心よりお瀌申し䞊げたす :bow: ちなみに別な問い合わせフォヌムで聞いおいお、その埌に知ったのですがこの手の内容は Qiita Discussions で聞いた方が良いらしいですね。CLIのActionsに぀いお改善案が思い぀きそうな気がするので、もし思い぀いたら投皿しおみようず思いたす ↩

19
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
4